Mercurial > libavformat.hg
annotate rtp.c @ 169:7c084ad75a99 libavformat
10l
author | michaelni |
---|---|
date | Sat, 12 Jul 2003 16:55:15 +0000 |
parents | 25062c9b1f86 |
children | 38f64fabb24b |
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; |
101 uint32_t last_rtcp_timestamp; | |
0 | 102 /* rtcp sender statistics */ |
103 unsigned int packet_count; | |
104 unsigned int octet_count; | |
105 unsigned int last_octet_count; | |
106 int first_packet; | |
107 /* buffer for output */ | |
65 | 108 uint8_t buf[RTP_MAX_PACKET_LENGTH]; |
109 uint8_t *buf_ptr; | |
0 | 110 } RTPContext; |
111 | |
112 int rtp_get_codec_info(AVCodecContext *codec, int payload_type) | |
113 { | |
114 switch(payload_type) { | |
115 case RTP_PT_ULAW: | |
116 codec->codec_id = CODEC_ID_PCM_MULAW; | |
117 codec->channels = 1; | |
118 codec->sample_rate = 8000; | |
119 break; | |
120 case RTP_PT_ALAW: | |
121 codec->codec_id = CODEC_ID_PCM_ALAW; | |
122 codec->channels = 1; | |
123 codec->sample_rate = 8000; | |
124 break; | |
125 case RTP_PT_S16BE_STEREO: | |
126 codec->codec_id = CODEC_ID_PCM_S16BE; | |
127 codec->channels = 2; | |
128 codec->sample_rate = 44100; | |
129 break; | |
130 case RTP_PT_S16BE_MONO: | |
131 codec->codec_id = CODEC_ID_PCM_S16BE; | |
132 codec->channels = 1; | |
133 codec->sample_rate = 44100; | |
134 break; | |
135 case RTP_PT_MPEGAUDIO: | |
136 codec->codec_id = CODEC_ID_MP2; | |
137 break; | |
138 case RTP_PT_JPEG: | |
139 codec->codec_id = CODEC_ID_MJPEG; | |
140 break; | |
141 case RTP_PT_MPEGVIDEO: | |
142 codec->codec_id = CODEC_ID_MPEG1VIDEO; | |
143 break; | |
144 default: | |
145 return -1; | |
146 } | |
147 return 0; | |
148 } | |
149 | |
150 /* return < 0 if unknown payload type */ | |
151 int rtp_get_payload_type(AVCodecContext *codec) | |
152 { | |
153 int payload_type; | |
154 | |
155 /* compute the payload type */ | |
156 payload_type = -1; | |
157 switch(codec->codec_id) { | |
158 case CODEC_ID_PCM_MULAW: | |
159 payload_type = RTP_PT_ULAW; | |
160 break; | |
161 case CODEC_ID_PCM_ALAW: | |
162 payload_type = RTP_PT_ALAW; | |
163 break; | |
164 case CODEC_ID_PCM_S16BE: | |
165 if (codec->channels == 1) { | |
166 payload_type = RTP_PT_S16BE_MONO; | |
167 } else if (codec->channels == 2) { | |
168 payload_type = RTP_PT_S16BE_STEREO; | |
169 } | |
170 break; | |
171 case CODEC_ID_MP2: | |
172 case CODEC_ID_MP3LAME: | |
173 payload_type = RTP_PT_MPEGAUDIO; | |
174 break; | |
175 case CODEC_ID_MJPEG: | |
176 payload_type = RTP_PT_JPEG; | |
177 break; | |
178 case CODEC_ID_MPEG1VIDEO: | |
179 payload_type = RTP_PT_MPEGVIDEO; | |
180 break; | |
181 default: | |
182 break; | |
183 } | |
184 return payload_type; | |
185 } | |
186 | |
65 | 187 static inline uint32_t decode_be32(const uint8_t *p) |
0 | 188 { |
189 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | |
190 } | |
191 | |
65 | 192 static inline uint32_t decode_be64(const uint8_t *p) |
0 | 193 { |
65 | 194 return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4); |
0 | 195 } |
196 | |
197 static int rtcp_parse_packet(AVFormatContext *s1, const unsigned char *buf, int len) | |
198 { | |
199 RTPContext *s = s1->priv_data; | |
200 | |
201 if (buf[1] != 200) | |
202 return -1; | |
203 s->last_rtcp_ntp_time = decode_be64(buf + 8); | |
204 s->last_rtcp_timestamp = decode_be32(buf + 16); | |
205 return 0; | |
206 } | |
207 | |
208 /** | |
209 * Parse an RTP packet directly sent as raw data. Can only be used if | |
210 * 'raw' is given as input file | |
211 * @param s1 media file context | |
212 * @param pkt returned packet | |
213 * @param buf input buffer | |
214 * @param len buffer len | |
215 * @return zero if no error. | |
216 */ | |
217 int rtp_parse_packet(AVFormatContext *s1, AVPacket *pkt, | |
218 const unsigned char *buf, int len) | |
219 { | |
220 RTPContext *s = s1->priv_data; | |
221 unsigned int ssrc, h; | |
222 int payload_type, seq, delta_timestamp; | |
223 AVStream *st; | |
65 | 224 uint32_t timestamp; |
0 | 225 |
226 if (len < 12) | |
227 return -1; | |
228 | |
229 if ((buf[0] & 0xc0) != (RTP_VERSION << 6)) | |
230 return -1; | |
231 if (buf[1] >= 200 && buf[1] <= 204) { | |
232 rtcp_parse_packet(s1, buf, len); | |
233 return -1; | |
234 } | |
235 payload_type = buf[1] & 0x7f; | |
236 seq = (buf[2] << 8) | buf[3]; | |
237 timestamp = decode_be32(buf + 4); | |
238 ssrc = decode_be32(buf + 8); | |
239 | |
240 if (s->payload_type < 0) { | |
241 s->payload_type = payload_type; | |
242 | |
243 if (payload_type == RTP_PT_MPEG2TS) { | |
244 /* XXX: special case : not a single codec but a whole stream */ | |
245 return -1; | |
246 } else { | |
247 st = av_new_stream(s1, 0); | |
248 if (!st) | |
249 return -1; | |
250 rtp_get_codec_info(&st->codec, payload_type); | |
251 } | |
252 } | |
253 | |
254 /* NOTE: we can handle only one payload type */ | |
255 if (s->payload_type != payload_type) | |
256 return -1; | |
257 #if defined(DEBUG) || 1 | |
258 if (seq != ((s->seq + 1) & 0xffff)) { | |
259 printf("RTP: PT=%02x: bad cseq %04x expected=%04x\n", | |
260 payload_type, seq, ((s->seq + 1) & 0xffff)); | |
261 } | |
262 s->seq = seq; | |
263 #endif | |
264 len -= 12; | |
265 buf += 12; | |
266 st = s1->streams[0]; | |
267 switch(st->codec.codec_id) { | |
268 case CODEC_ID_MP2: | |
269 /* better than nothing: skip mpeg audio RTP header */ | |
270 if (len <= 4) | |
271 return -1; | |
272 h = decode_be32(buf); | |
273 len -= 4; | |
274 buf += 4; | |
275 av_new_packet(pkt, len); | |
276 memcpy(pkt->data, buf, len); | |
277 break; | |
278 case CODEC_ID_MPEG1VIDEO: | |
279 /* better than nothing: skip mpeg audio RTP header */ | |
280 if (len <= 4) | |
281 return -1; | |
282 h = decode_be32(buf); | |
283 buf += 4; | |
284 len -= 4; | |
285 if (h & (1 << 26)) { | |
286 /* mpeg2 */ | |
287 if (len <= 4) | |
288 return -1; | |
289 buf += 4; | |
290 len -= 4; | |
291 } | |
292 av_new_packet(pkt, len); | |
293 memcpy(pkt->data, buf, len); | |
294 break; | |
295 default: | |
296 av_new_packet(pkt, len); | |
297 memcpy(pkt->data, buf, len); | |
298 break; | |
299 } | |
300 | |
301 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { | |
302 /* compute pts from timestamp with received ntp_time */ | |
303 delta_timestamp = timestamp - s->last_rtcp_timestamp; | |
304 /* XXX: do conversion, but not needed for mpeg at 90 KhZ */ | |
305 pkt->pts = s->last_rtcp_ntp_time + delta_timestamp; | |
306 } | |
307 return 0; | |
308 } | |
309 | |
310 static int rtp_read_header(AVFormatContext *s1, | |
311 AVFormatParameters *ap) | |
312 { | |
313 RTPContext *s = s1->priv_data; | |
314 s->payload_type = -1; | |
315 s->last_rtcp_ntp_time = AV_NOPTS_VALUE; | |
316 return 0; | |
317 } | |
318 | |
319 static int rtp_read_packet(AVFormatContext *s1, AVPacket *pkt) | |
320 { | |
321 char buf[RTP_MAX_PACKET_LENGTH]; | |
322 int ret; | |
323 | |
324 /* XXX: needs a better API for packet handling ? */ | |
325 for(;;) { | |
326 ret = url_read(url_fileno(&s1->pb), buf, sizeof(buf)); | |
327 if (ret < 0) | |
328 return AVERROR_IO; | |
329 if (rtp_parse_packet(s1, pkt, buf, ret) == 0) | |
330 break; | |
331 } | |
332 return 0; | |
333 } | |
334 | |
335 static int rtp_read_close(AVFormatContext *s1) | |
336 { | |
337 // RTPContext *s = s1->priv_data; | |
338 return 0; | |
339 } | |
340 | |
341 static int rtp_probe(AVProbeData *p) | |
342 { | |
343 if (strstart(p->filename, "rtp://", NULL)) | |
344 return AVPROBE_SCORE_MAX; | |
345 return 0; | |
346 } | |
347 | |
348 /* rtp output */ | |
349 | |
350 static int rtp_write_header(AVFormatContext *s1) | |
351 { | |
352 RTPContext *s = s1->priv_data; | |
353 int payload_type, max_packet_size; | |
354 AVStream *st; | |
355 | |
356 if (s1->nb_streams != 1) | |
357 return -1; | |
358 st = s1->streams[0]; | |
359 | |
360 payload_type = rtp_get_payload_type(&st->codec); | |
361 if (payload_type < 0) | |
362 payload_type = RTP_PT_PRIVATE; /* private payload type */ | |
363 s->payload_type = payload_type; | |
364 | |
365 s->base_timestamp = random(); | |
366 s->timestamp = s->base_timestamp; | |
367 s->ssrc = random(); | |
368 s->first_packet = 1; | |
369 | |
370 max_packet_size = url_fget_max_packet_size(&s1->pb); | |
371 if (max_packet_size <= 12) | |
372 return AVERROR_IO; | |
373 s->max_payload_size = max_packet_size - 12; | |
374 | |
375 switch(st->codec.codec_id) { | |
376 case CODEC_ID_MP2: | |
377 case CODEC_ID_MP3LAME: | |
378 s->buf_ptr = s->buf + 4; | |
379 s->cur_timestamp = 0; | |
380 break; | |
381 case CODEC_ID_MPEG1VIDEO: | |
382 s->cur_timestamp = 0; | |
383 break; | |
384 default: | |
385 s->buf_ptr = s->buf; | |
386 break; | |
387 } | |
388 | |
389 return 0; | |
390 } | |
391 | |
392 /* send an rtcp sender report packet */ | |
65 | 393 static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) |
0 | 394 { |
395 RTPContext *s = s1->priv_data; | |
396 #if defined(DEBUG) | |
397 printf("RTCP: %02x %Lx %x\n", s->payload_type, ntp_time, s->timestamp); | |
398 #endif | |
399 put_byte(&s1->pb, (RTP_VERSION << 6)); | |
400 put_byte(&s1->pb, 200); | |
401 put_be16(&s1->pb, 6); /* length in words - 1 */ | |
402 put_be32(&s1->pb, s->ssrc); | |
403 put_be64(&s1->pb, ntp_time); | |
404 put_be32(&s1->pb, s->timestamp); | |
405 put_be32(&s1->pb, s->packet_count); | |
406 put_be32(&s1->pb, s->octet_count); | |
407 put_flush_packet(&s1->pb); | |
408 } | |
409 | |
410 /* send an rtp packet. sequence number is incremented, but the caller | |
411 must update the timestamp itself */ | |
65 | 412 static void rtp_send_data(AVFormatContext *s1, uint8_t *buf1, int len) |
0 | 413 { |
414 RTPContext *s = s1->priv_data; | |
415 | |
416 #ifdef DEBUG | |
417 printf("rtp_send_data size=%d\n", len); | |
418 #endif | |
419 | |
420 /* build the RTP header */ | |
421 put_byte(&s1->pb, (RTP_VERSION << 6)); | |
422 put_byte(&s1->pb, s->payload_type & 0x7f); | |
423 put_be16(&s1->pb, s->seq); | |
424 put_be32(&s1->pb, s->timestamp); | |
425 put_be32(&s1->pb, s->ssrc); | |
426 | |
427 put_buffer(&s1->pb, buf1, len); | |
428 put_flush_packet(&s1->pb); | |
429 | |
430 s->seq++; | |
431 s->octet_count += len; | |
432 s->packet_count++; | |
433 } | |
434 | |
435 /* send an integer number of samples and compute time stamp and fill | |
436 the rtp send buffer before sending. */ | |
437 static void rtp_send_samples(AVFormatContext *s1, | |
65 | 438 uint8_t *buf1, int size, int sample_size) |
0 | 439 { |
440 RTPContext *s = s1->priv_data; | |
441 int len, max_packet_size, n; | |
442 | |
443 max_packet_size = (s->max_payload_size / sample_size) * sample_size; | |
444 /* not needed, but who nows */ | |
445 if ((size % sample_size) != 0) | |
446 av_abort(); | |
447 while (size > 0) { | |
448 len = (max_packet_size - (s->buf_ptr - s->buf)); | |
449 if (len > size) | |
450 len = size; | |
451 | |
452 /* copy data */ | |
453 memcpy(s->buf_ptr, buf1, len); | |
454 s->buf_ptr += len; | |
455 buf1 += len; | |
456 size -= len; | |
457 n = (s->buf_ptr - s->buf); | |
458 /* if buffer full, then send it */ | |
459 if (n >= max_packet_size) { | |
460 rtp_send_data(s1, s->buf, n); | |
461 s->buf_ptr = s->buf; | |
462 /* update timestamp */ | |
463 s->timestamp += n / sample_size; | |
464 } | |
465 } | |
466 } | |
467 | |
468 /* NOTE: we suppose that exactly one frame is given as argument here */ | |
469 /* XXX: test it */ | |
470 static void rtp_send_mpegaudio(AVFormatContext *s1, | |
65 | 471 uint8_t *buf1, int size) |
0 | 472 { |
473 RTPContext *s = s1->priv_data; | |
474 AVStream *st = s1->streams[0]; | |
475 int len, count, max_packet_size; | |
476 | |
477 max_packet_size = s->max_payload_size; | |
478 | |
479 /* test if we must flush because not enough space */ | |
480 len = (s->buf_ptr - s->buf); | |
481 if ((len + size) > max_packet_size) { | |
482 if (len > 4) { | |
483 rtp_send_data(s1, s->buf, s->buf_ptr - s->buf); | |
484 s->buf_ptr = s->buf + 4; | |
485 /* 90 KHz time stamp */ | |
486 s->timestamp = s->base_timestamp + | |
487 (s->cur_timestamp * 90000LL) / st->codec.sample_rate; | |
488 } | |
489 } | |
490 | |
491 /* add the packet */ | |
492 if (size > max_packet_size) { | |
493 /* big packet: fragment */ | |
494 count = 0; | |
495 while (size > 0) { | |
496 len = max_packet_size - 4; | |
497 if (len > size) | |
498 len = size; | |
499 /* build fragmented packet */ | |
500 s->buf[0] = 0; | |
501 s->buf[1] = 0; | |
502 s->buf[2] = count >> 8; | |
503 s->buf[3] = count; | |
504 memcpy(s->buf + 4, buf1, len); | |
505 rtp_send_data(s1, s->buf, len + 4); | |
506 size -= len; | |
507 buf1 += len; | |
508 count += len; | |
509 } | |
510 } else { | |
511 if (s->buf_ptr == s->buf + 4) { | |
512 /* no fragmentation possible */ | |
513 s->buf[0] = 0; | |
514 s->buf[1] = 0; | |
515 s->buf[2] = 0; | |
516 s->buf[3] = 0; | |
517 } | |
518 memcpy(s->buf_ptr, buf1, size); | |
519 s->buf_ptr += size; | |
520 } | |
521 s->cur_timestamp += st->codec.frame_size; | |
522 } | |
523 | |
524 /* NOTE: a single frame must be passed with sequence header if | |
525 needed. XXX: use slices. */ | |
526 static void rtp_send_mpegvideo(AVFormatContext *s1, | |
65 | 527 uint8_t *buf1, int size) |
0 | 528 { |
529 RTPContext *s = s1->priv_data; | |
530 AVStream *st = s1->streams[0]; | |
531 int len, h, max_packet_size; | |
65 | 532 uint8_t *q; |
0 | 533 |
534 max_packet_size = s->max_payload_size; | |
535 | |
536 while (size > 0) { | |
537 /* XXX: more correct headers */ | |
538 h = 0; | |
539 if (st->codec.sub_id == 2) | |
540 h |= 1 << 26; /* mpeg 2 indicator */ | |
541 q = s->buf; | |
542 *q++ = h >> 24; | |
543 *q++ = h >> 16; | |
544 *q++ = h >> 8; | |
545 *q++ = h; | |
546 | |
547 if (st->codec.sub_id == 2) { | |
548 h = 0; | |
549 *q++ = h >> 24; | |
550 *q++ = h >> 16; | |
551 *q++ = h >> 8; | |
552 *q++ = h; | |
553 } | |
554 | |
555 len = max_packet_size - (q - s->buf); | |
556 if (len > size) | |
557 len = size; | |
558 | |
559 memcpy(q, buf1, len); | |
560 q += len; | |
561 | |
562 /* 90 KHz time stamp */ | |
563 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
|
564 av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); |
0 | 565 rtp_send_data(s1, s->buf, q - s->buf); |
566 | |
567 buf1 += len; | |
568 size -= len; | |
569 } | |
570 s->cur_timestamp++; | |
571 } | |
572 | |
573 static void rtp_send_raw(AVFormatContext *s1, | |
65 | 574 uint8_t *buf1, int size) |
0 | 575 { |
576 RTPContext *s = s1->priv_data; | |
577 AVStream *st = s1->streams[0]; | |
578 int len, max_packet_size; | |
579 | |
580 max_packet_size = s->max_payload_size; | |
581 | |
582 while (size > 0) { | |
583 len = max_packet_size; | |
584 if (len > size) | |
585 len = size; | |
586 | |
587 /* 90 KHz time stamp */ | |
588 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
|
589 av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); |
0 | 590 rtp_send_data(s1, buf1, len); |
591 | |
592 buf1 += len; | |
593 size -= len; | |
594 } | |
595 s->cur_timestamp++; | |
596 } | |
597 | |
598 /* write an RTP packet. 'buf1' must contain a single specific frame. */ | |
599 static int rtp_write_packet(AVFormatContext *s1, int stream_index, | |
65 | 600 uint8_t *buf1, int size, int force_pts) |
0 | 601 { |
602 RTPContext *s = s1->priv_data; | |
603 AVStream *st = s1->streams[0]; | |
604 int rtcp_bytes; | |
65 | 605 int64_t ntp_time; |
0 | 606 |
607 #ifdef DEBUG | |
608 printf("%d: write len=%d\n", stream_index, size); | |
609 #endif | |
610 | |
611 /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */ | |
612 rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / | |
613 RTCP_TX_RATIO_DEN; | |
614 if (s->first_packet || rtcp_bytes >= 28) { | |
615 /* compute NTP time */ | |
65 | 616 ntp_time = force_pts; // ((int64_t)force_pts << 28) / 5625 |
0 | 617 rtcp_send_sr(s1, ntp_time); |
618 s->last_octet_count = s->octet_count; | |
619 s->first_packet = 0; | |
620 } | |
621 | |
622 switch(st->codec.codec_id) { | |
623 case CODEC_ID_PCM_MULAW: | |
624 case CODEC_ID_PCM_ALAW: | |
625 case CODEC_ID_PCM_U8: | |
626 case CODEC_ID_PCM_S8: | |
627 rtp_send_samples(s1, buf1, size, 1 * st->codec.channels); | |
628 break; | |
629 case CODEC_ID_PCM_U16BE: | |
630 case CODEC_ID_PCM_U16LE: | |
631 case CODEC_ID_PCM_S16BE: | |
632 case CODEC_ID_PCM_S16LE: | |
633 rtp_send_samples(s1, buf1, size, 2 * st->codec.channels); | |
634 break; | |
635 case CODEC_ID_MP2: | |
636 case CODEC_ID_MP3LAME: | |
637 rtp_send_mpegaudio(s1, buf1, size); | |
638 break; | |
639 case CODEC_ID_MPEG1VIDEO: | |
640 rtp_send_mpegvideo(s1, buf1, size); | |
641 break; | |
642 default: | |
643 /* better than nothing : send the codec raw data */ | |
644 rtp_send_raw(s1, buf1, size); | |
645 break; | |
646 } | |
647 return 0; | |
648 } | |
649 | |
650 static int rtp_write_trailer(AVFormatContext *s1) | |
651 { | |
652 // RTPContext *s = s1->priv_data; | |
653 return 0; | |
654 } | |
655 | |
656 AVInputFormat rtp_demux = { | |
657 "rtp", | |
658 "RTP input format", | |
659 sizeof(RTPContext), | |
660 rtp_probe, | |
661 rtp_read_header, | |
662 rtp_read_packet, | |
663 rtp_read_close, | |
664 .flags = AVFMT_NOHEADER, | |
665 }; | |
666 | |
667 AVOutputFormat rtp_mux = { | |
668 "rtp", | |
669 "RTP output format", | |
670 NULL, | |
671 NULL, | |
672 sizeof(RTPContext), | |
673 CODEC_ID_PCM_MULAW, | |
674 CODEC_ID_NONE, | |
675 rtp_write_header, | |
676 rtp_write_packet, | |
677 rtp_write_trailer, | |
678 }; | |
679 | |
680 int rtp_init(void) | |
681 { | |
682 av_register_output_format(&rtp_mux); | |
683 av_register_input_format(&rtp_demux); | |
684 return 0; | |
685 } |