2 * RTP input/output format
3 * Copyright (c) 2002 Fabrice Bellard.
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "bitstream.h"
28 #include "rtp_internal.h"
34 /* TODO: - add RTCP statistics reporting (should be optional).
36 - add support for h263/mpeg4 packetized output : IDEA: send a
37 buffer to 'rtp_write_packet' contains all the packets for ONE
38 frame. Each packet should have a four byte header containing
39 the length in big endian format (same trick as
40 'url_open_dyn_packet_buf')
43 /* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
44 AVRtpPayloadType_t AVRtpPayloadTypes[]=
46 {0, "PCMU", CODEC_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8000, 1},
47 {1, "Reserved", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
48 {2, "Reserved", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
49 {3, "GSM", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
50 {4, "G723", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
51 {5, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
52 {6, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1},
53 {7, "LPC", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
54 {8, "PCMA", CODEC_TYPE_AUDIO, CODEC_ID_PCM_ALAW, 8000, 1},
55 {9, "G722", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
56 {10, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 2},
57 {11, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1},
58 {12, "QCELP", CODEC_TYPE_AUDIO, CODEC_ID_QCELP, 8000, 1},
59 {13, "CN", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
60 {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, 90000, -1},
61 {15, "G728", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
62 {16, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1},
63 {17, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1},
64 {18, "G729", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
65 {19, "reserved", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
66 {20, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
67 {21, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
68 {22, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
69 {23, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
70 {24, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
71 {25, "CelB", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1},
72 {26, "JPEG", CODEC_TYPE_VIDEO, CODEC_ID_MJPEG, 90000, -1},
73 {27, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
74 {28, "nv", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1},
75 {29, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
76 {30, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
77 {31, "H261", CODEC_TYPE_VIDEO, CODEC_ID_H261, 90000, -1},
78 {32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG1VIDEO, 90000, -1},
79 {33, "MP2T", CODEC_TYPE_DATA, CODEC_ID_MPEG2TS, 90000, -1},
80 {34, "H263", CODEC_TYPE_VIDEO, CODEC_ID_H263, 90000, -1},
81 {35, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
82 {36, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
83 {37, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
84 {38, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
85 {39, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
86 {40, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
87 {41, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
88 {42, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
89 {43, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
90 {44, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
91 {45, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
92 {46, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
93 {47, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
94 {48, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
95 {49, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
96 {50, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
97 {51, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
98 {52, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
99 {53, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
100 {54, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
101 {55, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
102 {56, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
103 {57, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
104 {58, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
105 {59, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
106 {60, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
107 {61, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
108 {62, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
109 {63, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
110 {64, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
111 {65, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
112 {66, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
113 {67, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
114 {68, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
115 {69, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
116 {70, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
117 {71, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
118 {72, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
119 {73, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
120 {74, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
121 {75, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
122 {76, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
123 {77, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
124 {78, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
125 {79, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
126 {80, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
127 {81, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
128 {82, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
129 {83, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
130 {84, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
131 {85, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
132 {86, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
133 {87, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
134 {88, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
135 {89, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
136 {90, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
137 {91, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
138 {92, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
139 {93, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
140 {94, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
141 {95, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
142 {96, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
143 {97, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
144 {98, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
145 {99, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
146 {100, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
147 {101, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
148 {102, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
149 {103, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
150 {104, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
151 {105, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
152 {106, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
153 {107, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
154 {108, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
155 {109, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
156 {110, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
157 {111, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
158 {112, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
159 {113, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
160 {114, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
161 {115, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
162 {116, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
163 {117, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
164 {118, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
165 {119, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
166 {120, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
167 {121, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
168 {122, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
169 {123, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
170 {124, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
171 {125, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
172 {126, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
173 {127, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
174 {-1, "", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1}
177 /* statistics functions */
178 RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL;
180 static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4};
181 static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_AAC};
183 static void register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
185 handler->next= RTPFirstDynamicPayloadHandler;
186 RTPFirstDynamicPayloadHandler= handler;
189 void av_register_rtp_dynamic_payload_handlers(void)
191 register_dynamic_payload_handler(&mp4v_es_handler);
192 register_dynamic_payload_handler(&mpeg4_generic_handler);
193 register_dynamic_payload_handler(&ff_h264_dynamic_handler);
196 int rtp_get_codec_info(AVCodecContext *codec, int payload_type)
198 if (AVRtpPayloadTypes[payload_type].codec_id != CODEC_ID_NONE) {
199 codec->codec_type = AVRtpPayloadTypes[payload_type].codec_type;
200 codec->codec_id = AVRtpPayloadTypes[payload_type].codec_id;
201 if (AVRtpPayloadTypes[payload_type].audio_channels > 0)
202 codec->channels = AVRtpPayloadTypes[payload_type].audio_channels;
203 if (AVRtpPayloadTypes[payload_type].clock_rate > 0)
204 codec->sample_rate = AVRtpPayloadTypes[payload_type].clock_rate;
210 int rtp_get_payload_type(AVCodecContext *codec)
214 /* compute the payload type */
215 for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
216 if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
217 if (codec->codec_id == CODEC_ID_PCM_S16BE)
218 if (codec->channels != AVRtpPayloadTypes[i].audio_channels)
220 payload_type = AVRtpPayloadTypes[i].pt;
225 static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
229 s->last_rtcp_ntp_time = AV_RB64(buf + 8);
230 if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
231 s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
232 s->last_rtcp_timestamp = AV_RB32(buf + 16);
236 #define RTP_SEQ_MOD (1<<16)
239 * called on parse open packet
241 static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // called on parse open packet.
243 memset(s, 0, sizeof(RTPStatistics));
244 s->max_seq= base_sequence;
249 * called whenever there is a large jump in sequence numbers, or when they get out of probation...
251 static void rtp_init_sequence(RTPStatistics *s, uint16_t seq)
256 s->bad_seq= RTP_SEQ_MOD + 1;
258 s->expected_prior= 0;
259 s->received_prior= 0;
265 * returns 1 if we should handle this packet.
267 static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
269 uint16_t udelta= seq - s->max_seq;
270 const int MAX_DROPOUT= 3000;
271 const int MAX_MISORDER = 100;
272 const int MIN_SEQUENTIAL = 2;
274 /* source not valid until MIN_SEQUENTIAL packets with sequence seq. numbers have been received */
277 if(seq==s->max_seq + 1) {
280 if(s->probation==0) {
281 rtp_init_sequence(s, seq);
286 s->probation= MIN_SEQUENTIAL - 1;
289 } else if (udelta < MAX_DROPOUT) {
290 // in order, with permissible gap
291 if(seq < s->max_seq) {
292 //sequence number wrapped; count antother 64k cycles
293 s->cycles += RTP_SEQ_MOD;
296 } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
297 // sequence made a large jump...
298 if(seq==s->bad_seq) {
299 // two sequential packets-- assume that the other side restarted without telling us; just resync.
300 rtp_init_sequence(s, seq);
302 s->bad_seq= (seq + 1) & (RTP_SEQ_MOD-1);
306 // duplicate or reordered packet...
314 * This function is currently unused; without a valid local ntp time, I don't see how we could calculate the
315 * difference between the arrival and sent timestamp. As a result, the jitter and transit statistics values
316 * never change. I left this in in case someone else can see a way. (rdm)
318 static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp)
320 uint32_t transit= arrival_timestamp - sent_timestamp;
323 d= FFABS(transit - s->transit);
324 s->jitter += d - ((s->jitter + 8)>>4);
328 int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
334 RTPStatistics *stats= &s->statistics;
336 uint32_t extended_max;
337 uint32_t expected_interval;
338 uint32_t received_interval;
339 uint32_t lost_interval;
342 uint64_t ntp_time= s->last_rtcp_ntp_time; // TODO: Get local ntp time?
344 if (!s->rtp_ctx || (count < 1))
347 /* TODO: I think this is way too often; RFC 1889 has algorithm for this */
348 /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
349 s->octet_count += count;
350 rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
352 rtcp_bytes /= 50; // mmu_man: that's enough for me... VLC sends much less btw !?
355 s->last_octet_count = s->octet_count;
357 if (url_open_dyn_buf(&pb) < 0)
361 put_byte(&pb, (RTP_VERSION << 6) + 1); /* 1 report block */
363 put_be16(&pb, 7); /* length in words - 1 */
364 put_be32(&pb, s->ssrc); // our own SSRC
365 put_be32(&pb, s->ssrc); // XXX: should be the server's here!
366 // some placeholders we should really fill...
368 extended_max= stats->cycles + stats->max_seq;
369 expected= extended_max - stats->base_seq + 1;
370 lost= expected - stats->received;
371 lost= FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
372 expected_interval= expected - stats->expected_prior;
373 stats->expected_prior= expected;
374 received_interval= stats->received - stats->received_prior;
375 stats->received_prior= stats->received;
376 lost_interval= expected_interval - received_interval;
377 if (expected_interval==0 || lost_interval<=0) fraction= 0;
378 else fraction = (lost_interval<<8)/expected_interval;
380 fraction= (fraction<<24) | lost;
382 put_be32(&pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */
383 put_be32(&pb, extended_max); /* max sequence received */
384 put_be32(&pb, stats->jitter>>4); /* jitter */
386 if(s->last_rtcp_ntp_time==AV_NOPTS_VALUE)
388 put_be32(&pb, 0); /* last SR timestamp */
389 put_be32(&pb, 0); /* delay since last SR */
391 uint32_t middle_32_bits= s->last_rtcp_ntp_time>>16; // this is valid, right? do we need to handle 64 bit values special?
392 uint32_t delay_since_last= ntp_time - s->last_rtcp_ntp_time;
394 put_be32(&pb, middle_32_bits); /* last SR timestamp */
395 put_be32(&pb, delay_since_last); /* delay since last SR */
399 put_byte(&pb, (RTP_VERSION << 6) + 1); /* 1 report block */
401 len = strlen(s->hostname);
402 put_be16(&pb, (6 + len + 3) / 4); /* length in words - 1 */
403 put_be32(&pb, s->ssrc);
406 put_buffer(&pb, s->hostname, len);
408 for (len = (6 + len) % 4; len % 4; len++) {
412 put_flush_packet(&pb);
413 len = url_close_dyn_buf(&pb, &buf);
414 if ((len > 0) && buf) {
417 printf("sending %d bytes of RR\n", len);
419 result= url_write(s->rtp_ctx, buf, len);
421 printf("result from url_write: %d\n", result);
429 * open a new RTP parse context for stream 'st'. 'st' can be NULL for
430 * MPEG2TS streams to indicate that they should be demuxed inside the
431 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
432 * TODO: change this to not take rtp_payload data, and use the new dynamic payload system.
434 RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, rtp_payload_data_t *rtp_payload_data)
438 s = av_mallocz(sizeof(RTPDemuxContext));
441 s->payload_type = payload_type;
442 s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
443 s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
446 s->rtp_payload_data = rtp_payload_data;
447 rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?
448 if (!strcmp(AVRtpPayloadTypes[payload_type].enc_name, "MP2T")) {
449 s->ts = mpegts_parse_open(s->ic);
455 switch(st->codec->codec_id) {
456 case CODEC_ID_MPEG1VIDEO:
457 case CODEC_ID_MPEG2VIDEO:
462 st->need_parsing = AVSTREAM_PARSE_FULL;
468 // needed to send back RTCP RR in RTSP sessions
470 gethostname(s->hostname, sizeof(s->hostname));
474 static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf)
476 int au_headers_length, au_header_size, i;
477 GetBitContext getbitcontext;
478 rtp_payload_data_t *infos;
480 infos = s->rtp_payload_data;
485 /* decode the first 2 bytes where are stored the AUHeader sections
487 au_headers_length = AV_RB16(buf);
489 if (au_headers_length > RTP_MAX_PACKET_LENGTH)
492 infos->au_headers_length_bytes = (au_headers_length + 7) / 8;
494 /* skip AU headers length section (2 bytes) */
497 init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8);
499 /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
500 au_header_size = infos->sizelength + infos->indexlength;
501 if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
504 infos->nb_au_headers = au_headers_length / au_header_size;
505 infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers);
507 /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
508 In my test, the FAAD decoder does not behave correctly when sending each AU one by one
509 but does when sending the whole as one big packet... */
510 infos->au_headers[0].size = 0;
511 infos->au_headers[0].index = 0;
512 for (i = 0; i < infos->nb_au_headers; ++i) {
513 infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength);
514 infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength);
517 infos->nb_au_headers = 1;
523 * This was the second switch in rtp_parse packet. Normalizes time, if required, sets stream_index, etc.
525 static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
527 switch(s->st->codec->codec_id) {
529 case CODEC_ID_MPEG1VIDEO:
530 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
534 /* XXX: is it really necessary to unify the timestamp base ? */
535 /* compute pts from timestamp with received ntp_time */
536 delta_timestamp = timestamp - s->last_rtcp_timestamp;
537 /* convert to 90 kHz without overflow */
538 addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14;
539 addend = (addend * 5625) >> 14;
540 pkt->pts = addend + delta_timestamp;
546 pkt->pts = timestamp;
549 /* no timestamp info yet */
552 pkt->stream_index = s->st->index;
556 * Parse an RTP or RTCP packet directly sent as a buffer.
557 * @param s RTP parse context.
558 * @param pkt returned packet
559 * @param buf input buffer or NULL to read the next packets
560 * @param len buffer len
561 * @return 0 if a packet is returned, 1 if a packet is returned and more can follow
562 * (use buf as NULL to read the next). -1 if no packet (error or no more packet).
564 int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
565 const uint8_t *buf, int len)
567 unsigned int ssrc, h;
568 int payload_type, seq, ret;
574 /* return the next packets, if any */
575 if(s->st && s->parse_packet) {
576 timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
577 rv= s->parse_packet(s, pkt, ×tamp, NULL, 0);
578 finalize_packet(s, pkt, timestamp);
581 // TODO: Move to a dynamic packet handler (like above)
582 if (s->read_buf_index >= s->read_buf_size)
584 ret = mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
585 s->read_buf_size - s->read_buf_index);
588 s->read_buf_index += ret;
589 if (s->read_buf_index < s->read_buf_size)
599 if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
601 if (buf[1] >= 200 && buf[1] <= 204) {
602 rtcp_parse_packet(s, buf, len);
605 payload_type = buf[1] & 0x7f;
606 seq = AV_RB16(buf + 2);
607 timestamp = AV_RB32(buf + 4);
608 ssrc = AV_RB32(buf + 8);
609 /* store the ssrc in the RTPDemuxContext */
612 /* NOTE: we can handle only one payload type */
613 if (s->payload_type != payload_type)
617 // only do something with this if all the rtp checks pass...
618 if(!rtp_valid_packet_in_sequence(&s->statistics, seq))
620 av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
621 payload_type, seq, ((s->seq + 1) & 0xffff));
630 /* specific MPEG2TS demux support */
631 ret = mpegts_parse_packet(s->ts, pkt, buf, len);
635 s->read_buf_size = len - ret;
636 memcpy(s->buf, buf + ret, s->read_buf_size);
637 s->read_buf_index = 0;
641 // at this point, the RTP header has been stripped; This is ASSUMING that there is only 1 CSRC, which in't wise.
642 switch(st->codec->codec_id) {
644 /* better than nothing: skip mpeg audio RTP header */
650 av_new_packet(pkt, len);
651 memcpy(pkt->data, buf, len);
653 case CODEC_ID_MPEG1VIDEO:
654 /* better than nothing: skip mpeg video RTP header */
667 av_new_packet(pkt, len);
668 memcpy(pkt->data, buf, len);
670 // moved from below, verbatim. this is because this section handles packets, and the lower switch handles
672 // TODO: Put this into a dynamic packet handler...
674 if (rtp_parse_mp4_au(s, buf))
677 rtp_payload_data_t *infos = s->rtp_payload_data;
680 buf += infos->au_headers_length_bytes + 2;
681 len -= infos->au_headers_length_bytes + 2;
683 /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
685 av_new_packet(pkt, infos->au_headers[0].size);
686 memcpy(pkt->data, buf, infos->au_headers[0].size);
687 buf += infos->au_headers[0].size;
688 len -= infos->au_headers[0].size;
690 s->read_buf_size = len;
695 if(s->parse_packet) {
696 rv= s->parse_packet(s, pkt, ×tamp, buf, len);
698 av_new_packet(pkt, len);
699 memcpy(pkt->data, buf, len);
704 // now perform timestamp things....
705 finalize_packet(s, pkt, timestamp);
710 void rtp_parse_close(RTPDemuxContext *s)
712 // TODO: fold this into the protocol specific data fields.
713 if (!strcmp(AVRtpPayloadTypes[s->payload_type].enc_name, "MP2T")) {
714 mpegts_parse_close(s->ts);
721 static int rtp_write_header(AVFormatContext *s1)
723 RTPDemuxContext *s = s1->priv_data;
724 int payload_type, max_packet_size, n;
727 if (s1->nb_streams != 1)
731 payload_type = rtp_get_payload_type(st->codec);
732 if (payload_type < 0)
733 payload_type = RTP_PT_PRIVATE; /* private payload type */
734 s->payload_type = payload_type;
736 // following 2 FIXMies could be set based on the current time, theres normaly no info leak, as rtp will likely be transmitted immedeatly
737 s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
738 s->timestamp = s->base_timestamp;
739 s->ssrc = 0; /* FIXME: was random(), what should this be? */
742 max_packet_size = url_fget_max_packet_size(&s1->pb);
743 if (max_packet_size <= 12)
745 s->max_payload_size = max_packet_size - 12;
747 switch(st->codec->codec_id) {
750 s->buf_ptr = s->buf + 4;
751 s->cur_timestamp = 0;
753 case CODEC_ID_MPEG1VIDEO:
754 s->cur_timestamp = 0;
756 case CODEC_ID_MPEG2TS:
757 n = s->max_payload_size / TS_PACKET_SIZE;
760 s->max_payload_size = n * TS_PACKET_SIZE;
771 /* send an rtcp sender report packet */
772 static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
774 RTPDemuxContext *s = s1->priv_data;
776 printf("RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
778 put_byte(&s1->pb, (RTP_VERSION << 6));
779 put_byte(&s1->pb, 200);
780 put_be16(&s1->pb, 6); /* length in words - 1 */
781 put_be32(&s1->pb, s->ssrc);
782 put_be64(&s1->pb, ntp_time);
783 put_be32(&s1->pb, s->timestamp);
784 put_be32(&s1->pb, s->packet_count);
785 put_be32(&s1->pb, s->octet_count);
786 put_flush_packet(&s1->pb);
789 /* send an rtp packet. sequence number is incremented, but the caller
790 must update the timestamp itself */
791 static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
793 RTPDemuxContext *s = s1->priv_data;
796 printf("rtp_send_data size=%d\n", len);
799 /* build the RTP header */
800 put_byte(&s1->pb, (RTP_VERSION << 6));
801 put_byte(&s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
802 put_be16(&s1->pb, s->seq);
803 put_be32(&s1->pb, s->timestamp);
804 put_be32(&s1->pb, s->ssrc);
806 put_buffer(&s1->pb, buf1, len);
807 put_flush_packet(&s1->pb);
810 s->octet_count += len;
814 /* send an integer number of samples and compute time stamp and fill
815 the rtp send buffer before sending. */
816 static void rtp_send_samples(AVFormatContext *s1,
817 const uint8_t *buf1, int size, int sample_size)
819 RTPDemuxContext *s = s1->priv_data;
820 int len, max_packet_size, n;
822 max_packet_size = (s->max_payload_size / sample_size) * sample_size;
823 /* not needed, but who nows */
824 if ((size % sample_size) != 0)
827 len = (max_packet_size - (s->buf_ptr - s->buf));
832 memcpy(s->buf_ptr, buf1, len);
836 n = (s->buf_ptr - s->buf);
837 /* if buffer full, then send it */
838 if (n >= max_packet_size) {
839 rtp_send_data(s1, s->buf, n, 0);
841 /* update timestamp */
842 s->timestamp += n / sample_size;
847 /* NOTE: we suppose that exactly one frame is given as argument here */
849 static void rtp_send_mpegaudio(AVFormatContext *s1,
850 const uint8_t *buf1, int size)
852 RTPDemuxContext *s = s1->priv_data;
853 AVStream *st = s1->streams[0];
854 int len, count, max_packet_size;
856 max_packet_size = s->max_payload_size;
858 /* test if we must flush because not enough space */
859 len = (s->buf_ptr - s->buf);
860 if ((len + size) > max_packet_size) {
862 rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
863 s->buf_ptr = s->buf + 4;
864 /* 90 KHz time stamp */
865 s->timestamp = s->base_timestamp +
866 (s->cur_timestamp * 90000LL) / st->codec->sample_rate;
871 if (size > max_packet_size) {
872 /* big packet: fragment */
875 len = max_packet_size - 4;
878 /* build fragmented packet */
881 s->buf[2] = count >> 8;
883 memcpy(s->buf + 4, buf1, len);
884 rtp_send_data(s1, s->buf, len + 4, 0);
890 if (s->buf_ptr == s->buf + 4) {
891 /* no fragmentation possible */
897 memcpy(s->buf_ptr, buf1, size);
900 s->cur_timestamp += st->codec->frame_size;
903 /* NOTE: a single frame must be passed with sequence header if
904 needed. XXX: use slices. */
905 static void rtp_send_mpegvideo(AVFormatContext *s1,
906 const uint8_t *buf1, int size)
908 RTPDemuxContext *s = s1->priv_data;
909 AVStream *st = s1->streams[0];
910 int len, h, max_packet_size;
913 max_packet_size = s->max_payload_size;
916 /* XXX: more correct headers */
918 if (st->codec->sub_id == 2)
919 h |= 1 << 26; /* mpeg 2 indicator */
926 if (st->codec->sub_id == 2) {
934 len = max_packet_size - (q - s->buf);
938 memcpy(q, buf1, len);
941 /* 90 KHz time stamp */
942 s->timestamp = s->base_timestamp +
943 av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
944 rtp_send_data(s1, s->buf, q - s->buf, (len == size));
952 static void rtp_send_raw(AVFormatContext *s1,
953 const uint8_t *buf1, int size)
955 RTPDemuxContext *s = s1->priv_data;
956 AVStream *st = s1->streams[0];
957 int len, max_packet_size;
959 max_packet_size = s->max_payload_size;
962 len = max_packet_size;
966 /* 90 KHz time stamp */
967 s->timestamp = s->base_timestamp +
968 av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
969 rtp_send_data(s1, buf1, len, (len == size));
977 /* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
978 static void rtp_send_mpegts_raw(AVFormatContext *s1,
979 const uint8_t *buf1, int size)
981 RTPDemuxContext *s = s1->priv_data;
984 while (size >= TS_PACKET_SIZE) {
985 len = s->max_payload_size - (s->buf_ptr - s->buf);
988 memcpy(s->buf_ptr, buf1, len);
993 out_len = s->buf_ptr - s->buf;
994 if (out_len >= s->max_payload_size) {
995 rtp_send_data(s1, s->buf, out_len, 0);
1001 /* write an RTP packet. 'buf1' must contain a single specific frame. */
1002 static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
1004 RTPDemuxContext *s = s1->priv_data;
1005 AVStream *st = s1->streams[0];
1008 int size= pkt->size;
1009 uint8_t *buf1= pkt->data;
1012 printf("%d: write len=%d\n", pkt->stream_index, size);
1015 /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
1016 rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
1018 if (s->first_packet || rtcp_bytes >= 28) {
1019 /* compute NTP time */
1020 /* XXX: 90 kHz timestamp hardcoded */
1021 ntp_time = (pkt->pts << 28) / 5625;
1022 rtcp_send_sr(s1, ntp_time);
1023 s->last_octet_count = s->octet_count;
1024 s->first_packet = 0;
1027 switch(st->codec->codec_id) {
1028 case CODEC_ID_PCM_MULAW:
1029 case CODEC_ID_PCM_ALAW:
1030 case CODEC_ID_PCM_U8:
1031 case CODEC_ID_PCM_S8:
1032 rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
1034 case CODEC_ID_PCM_U16BE:
1035 case CODEC_ID_PCM_U16LE:
1036 case CODEC_ID_PCM_S16BE:
1037 case CODEC_ID_PCM_S16LE:
1038 rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
1042 rtp_send_mpegaudio(s1, buf1, size);
1044 case CODEC_ID_MPEG1VIDEO:
1045 rtp_send_mpegvideo(s1, buf1, size);
1047 case CODEC_ID_MPEG2TS:
1048 rtp_send_mpegts_raw(s1, buf1, size);
1051 /* better than nothing : send the codec raw data */
1052 rtp_send_raw(s1, buf1, size);
1058 AVOutputFormat rtp_muxer = {
1060 "RTP output format",
1063 sizeof(RTPDemuxContext),