Mercurial > libavformat.hg
annotate rtp.c @ 251:300c94a708f7 libavformat
remove unused AMREXTRALIBS
author | bellard |
---|---|
date | Tue, 16 Sep 2003 20:29:19 +0000 |
parents | 3d92f793fd67 |
children | 6091b76cfc2a |
rev | line source |
---|---|
0 | 1 /* |
2 * RTP input/output format | |
3 * Copyright (c) 2002 Fabrice Bellard. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avformat.h" | |
20 | |
21 #include <unistd.h> | |
22 #include <sys/types.h> | |
23 #include <sys/socket.h> | |
24 #include <netinet/in.h> | |
25 #ifndef __BEOS__ | |
26 # include <arpa/inet.h> | |
27 #else | |
28 # include "barpainet.h" | |
29 #endif | |
30 #include <netdb.h> | |
31 | |
32 //#define DEBUG | |
33 | |
34 | |
35 /* TODO: - add RTCP statistics reporting (should be optional). | |
36 | |
37 - add support for h263/mpeg4 packetized output : IDEA: send a | |
38 buffer to 'rtp_write_packet' contains all the packets for ONE | |
39 frame. Each packet should have a four byte header containing | |
40 the length in big endian format (same trick as | |
41 'url_open_dyn_packet_buf') | |
42 */ | |
43 | |
44 #define RTP_VERSION 2 | |
45 | |
46 #define RTP_MAX_SDES 256 /* maximum text length for SDES */ | |
47 | |
48 /* RTCP paquets use 0.5 % of the bandwidth */ | |
49 #define RTCP_TX_RATIO_NUM 5 | |
50 #define RTCP_TX_RATIO_DEN 1000 | |
51 | |
52 typedef enum { | |
53 RTCP_SR = 200, | |
54 RTCP_RR = 201, | |
55 RTCP_SDES = 202, | |
56 RTCP_BYE = 203, | |
57 RTCP_APP = 204 | |
58 } rtcp_type_t; | |
59 | |
60 typedef enum { | |
61 RTCP_SDES_END = 0, | |
62 RTCP_SDES_CNAME = 1, | |
63 RTCP_SDES_NAME = 2, | |
64 RTCP_SDES_EMAIL = 3, | |
65 RTCP_SDES_PHONE = 4, | |
66 RTCP_SDES_LOC = 5, | |
67 RTCP_SDES_TOOL = 6, | |
68 RTCP_SDES_NOTE = 7, | |
69 RTCP_SDES_PRIV = 8, | |
70 RTCP_SDES_IMG = 9, | |
71 RTCP_SDES_DOOR = 10, | |
72 RTCP_SDES_SOURCE = 11 | |
73 } rtcp_sdes_type_t; | |
74 | |
75 enum RTPPayloadType { | |
76 RTP_PT_ULAW = 0, | |
77 RTP_PT_GSM = 3, | |
78 RTP_PT_G723 = 4, | |
79 RTP_PT_ALAW = 8, | |
80 RTP_PT_S16BE_STEREO = 10, | |
81 RTP_PT_S16BE_MONO = 11, | |
82 RTP_PT_MPEGAUDIO = 14, | |
83 RTP_PT_JPEG = 26, | |
84 RTP_PT_H261 = 31, | |
85 RTP_PT_MPEGVIDEO = 32, | |
86 RTP_PT_MPEG2TS = 33, | |
87 RTP_PT_H263 = 34, /* old H263 encapsulation */ | |
88 RTP_PT_PRIVATE = 96, | |
89 }; | |
90 | |
91 typedef struct RTPContext { | |
92 int payload_type; | |
65 | 93 uint32_t ssrc; |
94 uint16_t seq; | |
95 uint32_t timestamp; | |
96 uint32_t base_timestamp; | |
97 uint32_t cur_timestamp; | |
0 | 98 int max_payload_size; |
99 /* rtcp sender statistics receive */ | |
65 | 100 int64_t last_rtcp_ntp_time; |
173 | 101 int64_t first_rtcp_ntp_time; |
65 | 102 uint32_t last_rtcp_timestamp; |
0 | 103 /* rtcp sender statistics */ |
104 unsigned int packet_count; | |
105 unsigned int octet_count; | |
106 unsigned int last_octet_count; | |
107 int first_packet; | |
108 /* buffer for output */ | |
65 | 109 uint8_t buf[RTP_MAX_PACKET_LENGTH]; |
110 uint8_t *buf_ptr; | |
0 | 111 } RTPContext; |
112 | |
113 int rtp_get_codec_info(AVCodecContext *codec, int payload_type) | |
114 { | |
115 switch(payload_type) { | |
116 case RTP_PT_ULAW: | |
117 codec->codec_id = CODEC_ID_PCM_MULAW; | |
118 codec->channels = 1; | |
119 codec->sample_rate = 8000; | |
120 break; | |
121 case RTP_PT_ALAW: | |
122 codec->codec_id = CODEC_ID_PCM_ALAW; | |
123 codec->channels = 1; | |
124 codec->sample_rate = 8000; | |
125 break; | |
126 case RTP_PT_S16BE_STEREO: | |
127 codec->codec_id = CODEC_ID_PCM_S16BE; | |
128 codec->channels = 2; | |
129 codec->sample_rate = 44100; | |
130 break; | |
131 case RTP_PT_S16BE_MONO: | |
132 codec->codec_id = CODEC_ID_PCM_S16BE; | |
133 codec->channels = 1; | |
134 codec->sample_rate = 44100; | |
135 break; | |
136 case RTP_PT_MPEGAUDIO: | |
137 codec->codec_id = CODEC_ID_MP2; | |
138 break; | |
139 case RTP_PT_JPEG: | |
140 codec->codec_id = CODEC_ID_MJPEG; | |
141 break; | |
142 case RTP_PT_MPEGVIDEO: | |
143 codec->codec_id = CODEC_ID_MPEG1VIDEO; | |
144 break; | |
145 default: | |
146 return -1; | |
147 } | |
148 return 0; | |
149 } | |
150 | |
151 /* return < 0 if unknown payload type */ | |
152 int rtp_get_payload_type(AVCodecContext *codec) | |
153 { | |
154 int payload_type; | |
155 | |
156 /* compute the payload type */ | |
157 payload_type = -1; | |
158 switch(codec->codec_id) { | |
159 case CODEC_ID_PCM_MULAW: | |
160 payload_type = RTP_PT_ULAW; | |
161 break; | |
162 case CODEC_ID_PCM_ALAW: | |
163 payload_type = RTP_PT_ALAW; | |
164 break; | |
165 case CODEC_ID_PCM_S16BE: | |
166 if (codec->channels == 1) { | |
167 payload_type = RTP_PT_S16BE_MONO; | |
168 } else if (codec->channels == 2) { | |
169 payload_type = RTP_PT_S16BE_STEREO; | |
170 } | |
171 break; | |
172 case CODEC_ID_MP2: | |
232 | 173 case CODEC_ID_MP3: |
0 | 174 payload_type = RTP_PT_MPEGAUDIO; |
175 break; | |
176 case CODEC_ID_MJPEG: | |
177 payload_type = RTP_PT_JPEG; | |
178 break; | |
179 case CODEC_ID_MPEG1VIDEO: | |
180 payload_type = RTP_PT_MPEGVIDEO; | |
181 break; | |
182 default: | |
183 break; | |
184 } | |
185 return payload_type; | |
186 } | |
187 | |
65 | 188 static inline uint32_t decode_be32(const uint8_t *p) |
0 | 189 { |
190 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | |
191 } | |
192 | |
173 | 193 static inline uint64_t decode_be64(const uint8_t *p) |
0 | 194 { |
65 | 195 return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4); |
0 | 196 } |
197 | |
198 static int rtcp_parse_packet(AVFormatContext *s1, const unsigned char *buf, int len) | |
199 { | |
200 RTPContext *s = s1->priv_data; | |
201 | |
202 if (buf[1] != 200) | |
203 return -1; | |
204 s->last_rtcp_ntp_time = decode_be64(buf + 8); | |
173 | 205 if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) |
206 s->first_rtcp_ntp_time = s->last_rtcp_ntp_time; | |
0 | 207 s->last_rtcp_timestamp = decode_be32(buf + 16); |
208 return 0; | |
209 } | |
210 | |
211 /** | |
212 * Parse an RTP packet directly sent as raw data. Can only be used if | |
213 * 'raw' is given as input file | |
214 * @param s1 media file context | |
215 * @param pkt returned packet | |
216 * @param buf input buffer | |
217 * @param len buffer len | |
218 * @return zero if no error. | |
219 */ | |
220 int rtp_parse_packet(AVFormatContext *s1, AVPacket *pkt, | |
221 const unsigned char *buf, int len) | |
222 { | |
223 RTPContext *s = s1->priv_data; | |
224 unsigned int ssrc, h; | |
225 int payload_type, seq, delta_timestamp; | |
226 AVStream *st; | |
65 | 227 uint32_t timestamp; |
0 | 228 |
229 if (len < 12) | |
230 return -1; | |
231 | |
232 if ((buf[0] & 0xc0) != (RTP_VERSION << 6)) | |
233 return -1; | |
234 if (buf[1] >= 200 && buf[1] <= 204) { | |
235 rtcp_parse_packet(s1, buf, len); | |
236 return -1; | |
237 } | |
238 payload_type = buf[1] & 0x7f; | |
239 seq = (buf[2] << 8) | buf[3]; | |
240 timestamp = decode_be32(buf + 4); | |
241 ssrc = decode_be32(buf + 8); | |
242 | |
243 if (s->payload_type < 0) { | |
244 s->payload_type = payload_type; | |
245 | |
246 if (payload_type == RTP_PT_MPEG2TS) { | |
247 /* XXX: special case : not a single codec but a whole stream */ | |
248 return -1; | |
249 } else { | |
250 st = av_new_stream(s1, 0); | |
251 if (!st) | |
252 return -1; | |
253 rtp_get_codec_info(&st->codec, payload_type); | |
254 } | |
255 } | |
256 | |
257 /* NOTE: we can handle only one payload type */ | |
258 if (s->payload_type != payload_type) | |
259 return -1; | |
260 #if defined(DEBUG) || 1 | |
261 if (seq != ((s->seq + 1) & 0xffff)) { | |
262 printf("RTP: PT=%02x: bad cseq %04x expected=%04x\n", | |
263 payload_type, seq, ((s->seq + 1) & 0xffff)); | |
264 } | |
265 s->seq = seq; | |
266 #endif | |
267 len -= 12; | |
268 buf += 12; | |
269 st = s1->streams[0]; | |
270 switch(st->codec.codec_id) { | |
271 case CODEC_ID_MP2: | |
272 /* better than nothing: skip mpeg audio RTP header */ | |
273 if (len <= 4) | |
274 return -1; | |
275 h = decode_be32(buf); | |
276 len -= 4; | |
277 buf += 4; | |
278 av_new_packet(pkt, len); | |
279 memcpy(pkt->data, buf, len); | |
280 break; | |
281 case CODEC_ID_MPEG1VIDEO: | |
282 /* better than nothing: skip mpeg audio RTP header */ | |
283 if (len <= 4) | |
284 return -1; | |
285 h = decode_be32(buf); | |
286 buf += 4; | |
287 len -= 4; | |
288 if (h & (1 << 26)) { | |
289 /* mpeg2 */ | |
290 if (len <= 4) | |
291 return -1; | |
292 buf += 4; | |
293 len -= 4; | |
294 } | |
295 av_new_packet(pkt, len); | |
296 memcpy(pkt->data, buf, len); | |
297 break; | |
298 default: | |
299 av_new_packet(pkt, len); | |
300 memcpy(pkt->data, buf, len); | |
301 break; | |
302 } | |
303 | |
173 | 304 switch(st->codec.codec_id) { |
305 case CODEC_ID_MP2: | |
306 case CODEC_ID_MPEG1VIDEO: | |
307 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { | |
308 int64_t addend; | |
309 /* XXX: is it really necessary to unify the timestamp base ? */ | |
310 /* compute pts from timestamp with received ntp_time */ | |
311 delta_timestamp = timestamp - s->last_rtcp_timestamp; | |
312 /* convert to 90 kHz without overflow */ | |
313 addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14; | |
314 addend = (addend * 5625) >> 14; | |
315 pkt->pts = addend + delta_timestamp; | |
316 } | |
317 break; | |
318 default: | |
319 /* no timestamp info yet */ | |
320 break; | |
0 | 321 } |
322 return 0; | |
323 } | |
324 | |
325 static int rtp_read_header(AVFormatContext *s1, | |
326 AVFormatParameters *ap) | |
327 { | |
328 RTPContext *s = s1->priv_data; | |
329 s->payload_type = -1; | |
330 s->last_rtcp_ntp_time = AV_NOPTS_VALUE; | |
173 | 331 s->first_rtcp_ntp_time = AV_NOPTS_VALUE; |
0 | 332 return 0; |
333 } | |
334 | |
335 static int rtp_read_packet(AVFormatContext *s1, AVPacket *pkt) | |
336 { | |
337 char buf[RTP_MAX_PACKET_LENGTH]; | |
338 int ret; | |
339 | |
340 /* XXX: needs a better API for packet handling ? */ | |
341 for(;;) { | |
342 ret = url_read(url_fileno(&s1->pb), buf, sizeof(buf)); | |
343 if (ret < 0) | |
344 return AVERROR_IO; | |
345 if (rtp_parse_packet(s1, pkt, buf, ret) == 0) | |
346 break; | |
347 } | |
348 return 0; | |
349 } | |
350 | |
351 static int rtp_read_close(AVFormatContext *s1) | |
352 { | |
353 // RTPContext *s = s1->priv_data; | |
354 return 0; | |
355 } | |
356 | |
357 static int rtp_probe(AVProbeData *p) | |
358 { | |
359 if (strstart(p->filename, "rtp://", NULL)) | |
360 return AVPROBE_SCORE_MAX; | |
361 return 0; | |
362 } | |
363 | |
364 /* rtp output */ | |
365 | |
366 static int rtp_write_header(AVFormatContext *s1) | |
367 { | |
368 RTPContext *s = s1->priv_data; | |
369 int payload_type, max_packet_size; | |
370 AVStream *st; | |
371 | |
372 if (s1->nb_streams != 1) | |
373 return -1; | |
374 st = s1->streams[0]; | |
375 | |
376 payload_type = rtp_get_payload_type(&st->codec); | |
377 if (payload_type < 0) | |
378 payload_type = RTP_PT_PRIVATE; /* private payload type */ | |
379 s->payload_type = payload_type; | |
380 | |
381 s->base_timestamp = random(); | |
382 s->timestamp = s->base_timestamp; | |
383 s->ssrc = random(); | |
384 s->first_packet = 1; | |
385 | |
386 max_packet_size = url_fget_max_packet_size(&s1->pb); | |
387 if (max_packet_size <= 12) | |
388 return AVERROR_IO; | |
389 s->max_payload_size = max_packet_size - 12; | |
390 | |
391 switch(st->codec.codec_id) { | |
392 case CODEC_ID_MP2: | |
232 | 393 case CODEC_ID_MP3: |
0 | 394 s->buf_ptr = s->buf + 4; |
395 s->cur_timestamp = 0; | |
396 break; | |
397 case CODEC_ID_MPEG1VIDEO: | |
398 s->cur_timestamp = 0; | |
399 break; | |
400 default: | |
401 s->buf_ptr = s->buf; | |
402 break; | |
403 } | |
404 | |
405 return 0; | |
406 } | |
407 | |
408 /* send an rtcp sender report packet */ | |
65 | 409 static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) |
0 | 410 { |
411 RTPContext *s = s1->priv_data; | |
412 #if defined(DEBUG) | |
413 printf("RTCP: %02x %Lx %x\n", s->payload_type, ntp_time, s->timestamp); | |
414 #endif | |
415 put_byte(&s1->pb, (RTP_VERSION << 6)); | |
416 put_byte(&s1->pb, 200); | |
417 put_be16(&s1->pb, 6); /* length in words - 1 */ | |
418 put_be32(&s1->pb, s->ssrc); | |
419 put_be64(&s1->pb, ntp_time); | |
420 put_be32(&s1->pb, s->timestamp); | |
421 put_be32(&s1->pb, s->packet_count); | |
422 put_be32(&s1->pb, s->octet_count); | |
423 put_flush_packet(&s1->pb); | |
424 } | |
425 | |
426 /* send an rtp packet. sequence number is incremented, but the caller | |
427 must update the timestamp itself */ | |
241 | 428 static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len) |
0 | 429 { |
430 RTPContext *s = s1->priv_data; | |
431 | |
432 #ifdef DEBUG | |
433 printf("rtp_send_data size=%d\n", len); | |
434 #endif | |
435 | |
436 /* build the RTP header */ | |
437 put_byte(&s1->pb, (RTP_VERSION << 6)); | |
438 put_byte(&s1->pb, s->payload_type & 0x7f); | |
439 put_be16(&s1->pb, s->seq); | |
440 put_be32(&s1->pb, s->timestamp); | |
441 put_be32(&s1->pb, s->ssrc); | |
442 | |
443 put_buffer(&s1->pb, buf1, len); | |
444 put_flush_packet(&s1->pb); | |
445 | |
446 s->seq++; | |
447 s->octet_count += len; | |
448 s->packet_count++; | |
449 } | |
450 | |
451 /* send an integer number of samples and compute time stamp and fill | |
452 the rtp send buffer before sending. */ | |
453 static void rtp_send_samples(AVFormatContext *s1, | |
241 | 454 const uint8_t *buf1, int size, int sample_size) |
0 | 455 { |
456 RTPContext *s = s1->priv_data; | |
457 int len, max_packet_size, n; | |
458 | |
459 max_packet_size = (s->max_payload_size / sample_size) * sample_size; | |
460 /* not needed, but who nows */ | |
461 if ((size % sample_size) != 0) | |
462 av_abort(); | |
463 while (size > 0) { | |
464 len = (max_packet_size - (s->buf_ptr - s->buf)); | |
465 if (len > size) | |
466 len = size; | |
467 | |
468 /* copy data */ | |
469 memcpy(s->buf_ptr, buf1, len); | |
470 s->buf_ptr += len; | |
471 buf1 += len; | |
472 size -= len; | |
473 n = (s->buf_ptr - s->buf); | |
474 /* if buffer full, then send it */ | |
475 if (n >= max_packet_size) { | |
476 rtp_send_data(s1, s->buf, n); | |
477 s->buf_ptr = s->buf; | |
478 /* update timestamp */ | |
479 s->timestamp += n / sample_size; | |
480 } | |
481 } | |
482 } | |
483 | |
484 /* NOTE: we suppose that exactly one frame is given as argument here */ | |
485 /* XXX: test it */ | |
486 static void rtp_send_mpegaudio(AVFormatContext *s1, | |
241 | 487 const uint8_t *buf1, int size) |
0 | 488 { |
489 RTPContext *s = s1->priv_data; | |
490 AVStream *st = s1->streams[0]; | |
491 int len, count, max_packet_size; | |
492 | |
493 max_packet_size = s->max_payload_size; | |
494 | |
495 /* test if we must flush because not enough space */ | |
496 len = (s->buf_ptr - s->buf); | |
497 if ((len + size) > max_packet_size) { | |
498 if (len > 4) { | |
499 rtp_send_data(s1, s->buf, s->buf_ptr - s->buf); | |
500 s->buf_ptr = s->buf + 4; | |
501 /* 90 KHz time stamp */ | |
502 s->timestamp = s->base_timestamp + | |
503 (s->cur_timestamp * 90000LL) / st->codec.sample_rate; | |
504 } | |
505 } | |
506 | |
507 /* add the packet */ | |
508 if (size > max_packet_size) { | |
509 /* big packet: fragment */ | |
510 count = 0; | |
511 while (size > 0) { | |
512 len = max_packet_size - 4; | |
513 if (len > size) | |
514 len = size; | |
515 /* build fragmented packet */ | |
516 s->buf[0] = 0; | |
517 s->buf[1] = 0; | |
518 s->buf[2] = count >> 8; | |
519 s->buf[3] = count; | |
520 memcpy(s->buf + 4, buf1, len); | |
521 rtp_send_data(s1, s->buf, len + 4); | |
522 size -= len; | |
523 buf1 += len; | |
524 count += len; | |
525 } | |
526 } else { | |
527 if (s->buf_ptr == s->buf + 4) { | |
528 /* no fragmentation possible */ | |
529 s->buf[0] = 0; | |
530 s->buf[1] = 0; | |
531 s->buf[2] = 0; | |
532 s->buf[3] = 0; | |
533 } | |
534 memcpy(s->buf_ptr, buf1, size); | |
535 s->buf_ptr += size; | |
536 } | |
537 s->cur_timestamp += st->codec.frame_size; | |
538 } | |
539 | |
540 /* NOTE: a single frame must be passed with sequence header if | |
541 needed. XXX: use slices. */ | |
542 static void rtp_send_mpegvideo(AVFormatContext *s1, | |
241 | 543 const uint8_t *buf1, int size) |
0 | 544 { |
545 RTPContext *s = s1->priv_data; | |
546 AVStream *st = s1->streams[0]; | |
547 int len, h, max_packet_size; | |
65 | 548 uint8_t *q; |
0 | 549 |
550 max_packet_size = s->max_payload_size; | |
551 | |
552 while (size > 0) { | |
553 /* XXX: more correct headers */ | |
554 h = 0; | |
555 if (st->codec.sub_id == 2) | |
556 h |= 1 << 26; /* mpeg 2 indicator */ | |
557 q = s->buf; | |
558 *q++ = h >> 24; | |
559 *q++ = h >> 16; | |
560 *q++ = h >> 8; | |
561 *q++ = h; | |
562 | |
563 if (st->codec.sub_id == 2) { | |
564 h = 0; | |
565 *q++ = h >> 24; | |
566 *q++ = h >> 16; | |
567 *q++ = h >> 8; | |
568 *q++ = h; | |
569 } | |
570 | |
571 len = max_packet_size - (q - s->buf); | |
572 if (len > size) | |
573 len = size; | |
574 | |
575 memcpy(q, buf1, len); | |
576 q += len; | |
577 | |
578 /* 90 KHz time stamp */ | |
579 s->timestamp = s->base_timestamp + | |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
580 av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); |
0 | 581 rtp_send_data(s1, s->buf, q - s->buf); |
582 | |
583 buf1 += len; | |
584 size -= len; | |
585 } | |
586 s->cur_timestamp++; | |
587 } | |
588 | |
589 static void rtp_send_raw(AVFormatContext *s1, | |
241 | 590 const uint8_t *buf1, int size) |
0 | 591 { |
592 RTPContext *s = s1->priv_data; | |
593 AVStream *st = s1->streams[0]; | |
594 int len, max_packet_size; | |
595 | |
596 max_packet_size = s->max_payload_size; | |
597 | |
598 while (size > 0) { | |
599 len = max_packet_size; | |
600 if (len > size) | |
601 len = size; | |
602 | |
603 /* 90 KHz time stamp */ | |
604 s->timestamp = s->base_timestamp + | |
85
25062c9b1f86
per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents:
65
diff
changeset
|
605 av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); |
0 | 606 rtp_send_data(s1, buf1, len); |
607 | |
608 buf1 += len; | |
609 size -= len; | |
610 } | |
611 s->cur_timestamp++; | |
612 } | |
613 | |
614 /* write an RTP packet. 'buf1' must contain a single specific frame. */ | |
615 static int rtp_write_packet(AVFormatContext *s1, int stream_index, | |
241 | 616 const uint8_t *buf1, int size, int64_t pts) |
0 | 617 { |
618 RTPContext *s = s1->priv_data; | |
619 AVStream *st = s1->streams[0]; | |
620 int rtcp_bytes; | |
65 | 621 int64_t ntp_time; |
0 | 622 |
623 #ifdef DEBUG | |
624 printf("%d: write len=%d\n", stream_index, size); | |
625 #endif | |
626 | |
627 /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */ | |
628 rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / | |
629 RTCP_TX_RATIO_DEN; | |
630 if (s->first_packet || rtcp_bytes >= 28) { | |
631 /* compute NTP time */ | |
173 | 632 /* XXX: 90 kHz timestamp hardcoded */ |
241 | 633 ntp_time = (pts << 28) / 5625; |
0 | 634 rtcp_send_sr(s1, ntp_time); |
635 s->last_octet_count = s->octet_count; | |
636 s->first_packet = 0; | |
637 } | |
638 | |
639 switch(st->codec.codec_id) { | |
640 case CODEC_ID_PCM_MULAW: | |
641 case CODEC_ID_PCM_ALAW: | |
642 case CODEC_ID_PCM_U8: | |
643 case CODEC_ID_PCM_S8: | |
644 rtp_send_samples(s1, buf1, size, 1 * st->codec.channels); | |
645 break; | |
646 case CODEC_ID_PCM_U16BE: | |
647 case CODEC_ID_PCM_U16LE: | |
648 case CODEC_ID_PCM_S16BE: | |
649 case CODEC_ID_PCM_S16LE: | |
650 rtp_send_samples(s1, buf1, size, 2 * st->codec.channels); | |
651 break; | |
652 case CODEC_ID_MP2: | |
232 | 653 case CODEC_ID_MP3: |
0 | 654 rtp_send_mpegaudio(s1, buf1, size); |
655 break; | |
656 case CODEC_ID_MPEG1VIDEO: | |
657 rtp_send_mpegvideo(s1, buf1, size); | |
658 break; | |
659 default: | |
660 /* better than nothing : send the codec raw data */ | |
661 rtp_send_raw(s1, buf1, size); | |
662 break; | |
663 } | |
664 return 0; | |
665 } | |
666 | |
667 static int rtp_write_trailer(AVFormatContext *s1) | |
668 { | |
669 // RTPContext *s = s1->priv_data; | |
670 return 0; | |
671 } | |
672 | |
673 AVInputFormat rtp_demux = { | |
674 "rtp", | |
675 "RTP input format", | |
676 sizeof(RTPContext), | |
677 rtp_probe, | |
678 rtp_read_header, | |
679 rtp_read_packet, | |
680 rtp_read_close, | |
681 .flags = AVFMT_NOHEADER, | |
682 }; | |
683 | |
684 AVOutputFormat rtp_mux = { | |
685 "rtp", | |
686 "RTP output format", | |
687 NULL, | |
688 NULL, | |
689 sizeof(RTPContext), | |
690 CODEC_ID_PCM_MULAW, | |
691 CODEC_ID_NONE, | |
692 rtp_write_header, | |
693 rtp_write_packet, | |
694 rtp_write_trailer, | |
695 }; | |
696 | |
697 int rtp_init(void) | |
698 { | |
699 av_register_output_format(&rtp_mux); | |
700 av_register_input_format(&rtp_demux); | |
701 return 0; | |
702 } |