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