VirtualBox

source: vbox/trunk/src/libs/ffmpeg-20060710/libavformat/rtp.c@ 11551

Last change on this file since 11551 was 5776, checked in by vboxsync, 17 years ago

ffmpeg: exported to OSE

File size: 30.4 KB
Line 
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#include "avformat.h"
20#include "mpegts.h"
21#include "bitstream.h"
22
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <netinet/in.h>
27#ifndef __BEOS__
28# include <arpa/inet.h>
29#else
30# include "barpainet.h"
31#endif
32#include <netdb.h>
33
34//#define DEBUG
35
36
37/* TODO: - add RTCP statistics reporting (should be optional).
38
39 - add support for h263/mpeg4 packetized output : IDEA: send a
40 buffer to 'rtp_write_packet' contains all the packets for ONE
41 frame. Each packet should have a four byte header containing
42 the length in big endian format (same trick as
43 'url_open_dyn_packet_buf')
44*/
45
46/* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
47AVRtpPayloadType_t AVRtpPayloadTypes[]=
48{
49 {0, "PCMU", CODEC_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8000, 1},
50 {1, "Reserved", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
51 {2, "Reserved", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
52 {3, "GSM", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
53 {4, "G723", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
54 {5, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
55 {6, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1},
56 {7, "LPC", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
57 {8, "PCMA", CODEC_TYPE_AUDIO, CODEC_ID_PCM_ALAW, 8000, 1},
58 {9, "G722", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
59 {10, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 2},
60 {11, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1},
61 {12, "QCELP", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
62 {13, "CN", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
63 {14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, 90000, -1},
64 {15, "G728", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
65 {16, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1},
66 {17, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1},
67 {18, "G729", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1},
68 {19, "reserved", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
69 {20, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
70 {21, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
71 {22, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
72 {23, "unassigned", CODEC_TYPE_AUDIO, CODEC_ID_NONE, -1, -1},
73 {24, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
74 {25, "CelB", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1},
75 {26, "JPEG", CODEC_TYPE_VIDEO, CODEC_ID_MJPEG, 90000, -1},
76 {27, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
77 {28, "nv", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1},
78 {29, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
79 {30, "unassigned", CODEC_TYPE_VIDEO, CODEC_ID_NONE, -1, -1},
80 {31, "H261", CODEC_TYPE_VIDEO, CODEC_ID_H261, 90000, -1},
81 {32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG1VIDEO, 90000, -1},
82 {33, "MP2T", CODEC_TYPE_DATA, CODEC_ID_MPEG2TS, 90000, -1},
83 {34, "H263", CODEC_TYPE_VIDEO, CODEC_ID_H263, 90000, -1},
84 {35, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
85 {36, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
86 {37, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
87 {38, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
88 {39, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
89 {40, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
90 {41, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
91 {42, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
92 {43, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
93 {44, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
94 {45, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
95 {46, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
96 {47, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
97 {48, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
98 {49, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
99 {50, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
100 {51, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
101 {52, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
102 {53, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
103 {54, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
104 {55, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
105 {56, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
106 {57, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
107 {58, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
108 {59, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
109 {60, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
110 {61, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
111 {62, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
112 {63, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
113 {64, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
114 {65, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
115 {66, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
116 {67, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
117 {68, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
118 {69, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
119 {70, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
120 {71, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
121 {72, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
122 {73, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
123 {74, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
124 {75, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
125 {76, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
126 {77, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
127 {78, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
128 {79, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
129 {80, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
130 {81, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
131 {82, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
132 {83, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
133 {84, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
134 {85, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
135 {86, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
136 {87, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
137 {88, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
138 {89, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
139 {90, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
140 {91, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
141 {92, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
142 {93, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
143 {94, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
144 {95, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
145 {96, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
146 {97, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
147 {98, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
148 {99, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
149 {100, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
150 {101, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
151 {102, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
152 {103, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
153 {104, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
154 {105, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
155 {106, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
156 {107, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
157 {108, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
158 {109, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
159 {110, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
160 {111, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
161 {112, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
162 {113, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
163 {114, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
164 {115, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
165 {116, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
166 {117, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
167 {118, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
168 {119, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
169 {120, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
170 {121, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
171 {122, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
172 {123, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
173 {124, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
174 {125, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
175 {126, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
176 {127, "dynamic", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
177 {-1, "", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1}
178};
179
180AVRtpDynamicPayloadType_t AVRtpDynamicPayloadTypes[]=
181{
182 {"MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4},
183 {"mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_MPEG4AAC},
184 {"", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE}
185};
186
187struct RTPDemuxContext {
188 AVFormatContext *ic;
189 AVStream *st;
190 int payload_type;
191 uint32_t ssrc;
192 uint16_t seq;
193 uint32_t timestamp;
194 uint32_t base_timestamp;
195 uint32_t cur_timestamp;
196 int max_payload_size;
197 MpegTSContext *ts; /* only used for MP2T payloads */
198 int read_buf_index;
199 int read_buf_size;
200
201 /* rtcp sender statistics receive */
202 int64_t last_rtcp_ntp_time;
203 int64_t first_rtcp_ntp_time;
204 uint32_t last_rtcp_timestamp;
205 /* rtcp sender statistics */
206 unsigned int packet_count;
207 unsigned int octet_count;
208 unsigned int last_octet_count;
209 int first_packet;
210 /* buffer for output */
211 uint8_t buf[RTP_MAX_PACKET_LENGTH];
212 uint8_t *buf_ptr;
213 /* special infos for au headers parsing */
214 rtp_payload_data_t *rtp_payload_data;
215};
216
217int rtp_get_codec_info(AVCodecContext *codec, int payload_type)
218{
219 if (AVRtpPayloadTypes[payload_type].codec_id != CODEC_ID_NONE) {
220 codec->codec_type = AVRtpPayloadTypes[payload_type].codec_type;
221 codec->codec_id = AVRtpPayloadTypes[payload_type].codec_id;
222 if (AVRtpPayloadTypes[payload_type].audio_channels > 0)
223 codec->channels = AVRtpPayloadTypes[payload_type].audio_channels;
224 if (AVRtpPayloadTypes[payload_type].clock_rate > 0)
225 codec->sample_rate = AVRtpPayloadTypes[payload_type].clock_rate;
226 return 0;
227 }
228 return -1;
229}
230
231/* return < 0 if unknown payload type */
232int rtp_get_payload_type(AVCodecContext *codec)
233{
234 int i, payload_type;
235
236 /* compute the payload type */
237 for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
238 if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
239 if (codec->codec_id == CODEC_ID_PCM_S16BE)
240 if (codec->channels != AVRtpPayloadTypes[i].audio_channels)
241 continue;
242 payload_type = AVRtpPayloadTypes[i].pt;
243 }
244 return payload_type;
245}
246
247static inline uint32_t decode_be32(const uint8_t *p)
248{
249 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
250}
251
252static inline uint64_t decode_be64(const uint8_t *p)
253{
254 return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4);
255}
256
257static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
258{
259 if (buf[1] != 200)
260 return -1;
261 s->last_rtcp_ntp_time = decode_be64(buf + 8);
262 if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
263 s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
264 s->last_rtcp_timestamp = decode_be32(buf + 16);
265 return 0;
266}
267
268/**
269 * open a new RTP parse context for stream 'st'. 'st' can be NULL for
270 * MPEG2TS streams to indicate that they should be demuxed inside the
271 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
272 */
273RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, int payload_type, rtp_payload_data_t *rtp_payload_data)
274{
275 RTPDemuxContext *s;
276
277 s = av_mallocz(sizeof(RTPDemuxContext));
278 if (!s)
279 return NULL;
280 s->payload_type = payload_type;
281 s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
282 s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
283 s->ic = s1;
284 s->st = st;
285 s->rtp_payload_data = rtp_payload_data;
286 if (!strcmp(AVRtpPayloadTypes[payload_type].enc_name, "MP2T")) {
287 s->ts = mpegts_parse_open(s->ic);
288 if (s->ts == NULL) {
289 av_free(s);
290 return NULL;
291 }
292 } else {
293 switch(st->codec->codec_id) {
294 case CODEC_ID_MPEG1VIDEO:
295 case CODEC_ID_MPEG2VIDEO:
296 case CODEC_ID_MP2:
297 case CODEC_ID_MP3:
298 case CODEC_ID_MPEG4:
299 st->need_parsing = 1;
300 break;
301 default:
302 break;
303 }
304 }
305 return s;
306}
307
308static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf)
309{
310 int au_headers_length, au_header_size, i;
311 GetBitContext getbitcontext;
312 rtp_payload_data_t *infos;
313
314 infos = s->rtp_payload_data;
315
316 if (infos == NULL)
317 return -1;
318
319 /* decode the first 2 bytes where are stored the AUHeader sections
320 length in bits */
321 au_headers_length = BE_16(buf);
322
323 if (au_headers_length > RTP_MAX_PACKET_LENGTH)
324 return -1;
325
326 infos->au_headers_length_bytes = (au_headers_length + 7) / 8;
327
328 /* skip AU headers length section (2 bytes) */
329 buf += 2;
330
331 init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8);
332
333 /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
334 au_header_size = infos->sizelength + infos->indexlength;
335 if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
336 return -1;
337
338 infos->nb_au_headers = au_headers_length / au_header_size;
339 infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers);
340
341 /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
342 In my test, the faad decoder doesnt behave correctly when sending each AU one by one
343 but does when sending the whole as one big packet... */
344 infos->au_headers[0].size = 0;
345 infos->au_headers[0].index = 0;
346 for (i = 0; i < infos->nb_au_headers; ++i) {
347 infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength);
348 infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength);
349 }
350
351 infos->nb_au_headers = 1;
352
353 return 0;
354}
355
356/**
357 * Parse an RTP or RTCP packet directly sent as a buffer.
358 * @param s RTP parse context.
359 * @param pkt returned packet
360 * @param buf input buffer or NULL to read the next packets
361 * @param len buffer len
362 * @return 0 if a packet is returned, 1 if a packet is returned and more can follow
363 * (use buf as NULL to read the next). -1 if no packet (error or no more packet).
364 */
365int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
366 const uint8_t *buf, int len)
367{
368 unsigned int ssrc, h;
369 int payload_type, seq, delta_timestamp, ret;
370 AVStream *st;
371 uint32_t timestamp;
372
373 if (!buf) {
374 /* return the next packets, if any */
375 if (s->read_buf_index >= s->read_buf_size)
376 return -1;
377 ret = mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
378 s->read_buf_size - s->read_buf_index);
379 if (ret < 0)
380 return -1;
381 s->read_buf_index += ret;
382 if (s->read_buf_index < s->read_buf_size)
383 return 1;
384 else
385 return 0;
386 }
387
388 if (len < 12)
389 return -1;
390
391 if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
392 return -1;
393 if (buf[1] >= 200 && buf[1] <= 204) {
394 rtcp_parse_packet(s, buf, len);
395 return -1;
396 }
397 payload_type = buf[1] & 0x7f;
398 seq = (buf[2] << 8) | buf[3];
399 timestamp = decode_be32(buf + 4);
400 ssrc = decode_be32(buf + 8);
401
402 /* NOTE: we can handle only one payload type */
403 if (s->payload_type != payload_type)
404 return -1;
405
406 st = s->st;
407#if defined(DEBUG) || 1
408 if (seq != ((s->seq + 1) & 0xffff)) {
409 av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
410 payload_type, seq, ((s->seq + 1) & 0xffff));
411 }
412#endif
413 s->seq = seq;
414 len -= 12;
415 buf += 12;
416
417 if (!st) {
418 /* specific MPEG2TS demux support */
419 ret = mpegts_parse_packet(s->ts, pkt, buf, len);
420 if (ret < 0)
421 return -1;
422 if (ret < len) {
423 s->read_buf_size = len - ret;
424 memcpy(s->buf, buf + ret, s->read_buf_size);
425 s->read_buf_index = 0;
426 return 1;
427 }
428 } else {
429 switch(st->codec->codec_id) {
430 case CODEC_ID_MP2:
431 /* better than nothing: skip mpeg audio RTP header */
432 if (len <= 4)
433 return -1;
434 h = decode_be32(buf);
435 len -= 4;
436 buf += 4;
437 av_new_packet(pkt, len);
438 memcpy(pkt->data, buf, len);
439 break;
440 case CODEC_ID_MPEG1VIDEO:
441 /* better than nothing: skip mpeg video RTP header */
442 if (len <= 4)
443 return -1;
444 h = decode_be32(buf);
445 buf += 4;
446 len -= 4;
447 if (h & (1 << 26)) {
448 /* mpeg2 */
449 if (len <= 4)
450 return -1;
451 buf += 4;
452 len -= 4;
453 }
454 av_new_packet(pkt, len);
455 memcpy(pkt->data, buf, len);
456 break;
457 default:
458 av_new_packet(pkt, len);
459 memcpy(pkt->data, buf, len);
460 break;
461 }
462
463 switch(st->codec->codec_id) {
464 case CODEC_ID_MP2:
465 case CODEC_ID_MPEG1VIDEO:
466 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
467 int64_t addend;
468 /* XXX: is it really necessary to unify the timestamp base ? */
469 /* compute pts from timestamp with received ntp_time */
470 delta_timestamp = timestamp - s->last_rtcp_timestamp;
471 /* convert to 90 kHz without overflow */
472 addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14;
473 addend = (addend * 5625) >> 14;
474 pkt->pts = addend + delta_timestamp;
475 }
476 break;
477 case CODEC_ID_MPEG4:
478 pkt->pts = timestamp;
479 break;
480 case CODEC_ID_MPEG4AAC:
481 if (rtp_parse_mp4_au(s, buf))
482 return -1;
483 {
484 rtp_payload_data_t *infos = s->rtp_payload_data;
485 if (infos == NULL)
486 return -1;
487 buf += infos->au_headers_length_bytes + 2;
488 len -= infos->au_headers_length_bytes + 2;
489
490 /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
491 one au_header */
492 av_new_packet(pkt, infos->au_headers[0].size);
493 memcpy(pkt->data, buf, infos->au_headers[0].size);
494 buf += infos->au_headers[0].size;
495 len -= infos->au_headers[0].size;
496 }
497 s->read_buf_size = len;
498 s->buf_ptr = (char *)buf;
499 pkt->stream_index = s->st->index;
500 return 0;
501 default:
502 /* no timestamp info yet */
503 break;
504 }
505 pkt->stream_index = s->st->index;
506 }
507 return 0;
508}
509
510void rtp_parse_close(RTPDemuxContext *s)
511{
512 if (!strcmp(AVRtpPayloadTypes[s->payload_type].enc_name, "MP2T")) {
513 mpegts_parse_close(s->ts);
514 }
515 av_free(s);
516}
517
518/* rtp output */
519
520static int rtp_write_header(AVFormatContext *s1)
521{
522 RTPDemuxContext *s = s1->priv_data;
523 int payload_type, max_packet_size, n;
524 AVStream *st;
525
526 if (s1->nb_streams != 1)
527 return -1;
528 st = s1->streams[0];
529
530 payload_type = rtp_get_payload_type(st->codec);
531 if (payload_type < 0)
532 payload_type = RTP_PT_PRIVATE; /* private payload type */
533 s->payload_type = payload_type;
534
535// following 2 FIXMies could be set based on the current time, theres normaly no info leak, as rtp will likely be transmitted immedeatly
536 s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
537 s->timestamp = s->base_timestamp;
538 s->ssrc = 0; /* FIXME: was random(), what should this be? */
539 s->first_packet = 1;
540
541 max_packet_size = url_fget_max_packet_size(&s1->pb);
542 if (max_packet_size <= 12)
543 return AVERROR_IO;
544 s->max_payload_size = max_packet_size - 12;
545
546 switch(st->codec->codec_id) {
547 case CODEC_ID_MP2:
548 case CODEC_ID_MP3:
549 s->buf_ptr = s->buf + 4;
550 s->cur_timestamp = 0;
551 break;
552 case CODEC_ID_MPEG1VIDEO:
553 s->cur_timestamp = 0;
554 break;
555 case CODEC_ID_MPEG2TS:
556 n = s->max_payload_size / TS_PACKET_SIZE;
557 if (n < 1)
558 n = 1;
559 s->max_payload_size = n * TS_PACKET_SIZE;
560 s->buf_ptr = s->buf;
561 break;
562 default:
563 s->buf_ptr = s->buf;
564 break;
565 }
566
567 return 0;
568}
569
570/* send an rtcp sender report packet */
571static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
572{
573 RTPDemuxContext *s = s1->priv_data;
574#if defined(DEBUG)
575 printf("RTCP: %02x %Lx %x\n", s->payload_type, ntp_time, s->timestamp);
576#endif
577 put_byte(&s1->pb, (RTP_VERSION << 6));
578 put_byte(&s1->pb, 200);
579 put_be16(&s1->pb, 6); /* length in words - 1 */
580 put_be32(&s1->pb, s->ssrc);
581 put_be64(&s1->pb, ntp_time);
582 put_be32(&s1->pb, s->timestamp);
583 put_be32(&s1->pb, s->packet_count);
584 put_be32(&s1->pb, s->octet_count);
585 put_flush_packet(&s1->pb);
586}
587
588/* send an rtp packet. sequence number is incremented, but the caller
589 must update the timestamp itself */
590static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
591{
592 RTPDemuxContext *s = s1->priv_data;
593
594#ifdef DEBUG
595 printf("rtp_send_data size=%d\n", len);
596#endif
597
598 /* build the RTP header */
599 put_byte(&s1->pb, (RTP_VERSION << 6));
600 put_byte(&s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
601 put_be16(&s1->pb, s->seq);
602 put_be32(&s1->pb, s->timestamp);
603 put_be32(&s1->pb, s->ssrc);
604
605 put_buffer(&s1->pb, buf1, len);
606 put_flush_packet(&s1->pb);
607
608 s->seq++;
609 s->octet_count += len;
610 s->packet_count++;
611}
612
613/* send an integer number of samples and compute time stamp and fill
614 the rtp send buffer before sending. */
615static void rtp_send_samples(AVFormatContext *s1,
616 const uint8_t *buf1, int size, int sample_size)
617{
618 RTPDemuxContext *s = s1->priv_data;
619 int len, max_packet_size, n;
620
621 max_packet_size = (s->max_payload_size / sample_size) * sample_size;
622 /* not needed, but who nows */
623 if ((size % sample_size) != 0)
624 av_abort();
625 while (size > 0) {
626 len = (max_packet_size - (s->buf_ptr - s->buf));
627 if (len > size)
628 len = size;
629
630 /* copy data */
631 memcpy(s->buf_ptr, buf1, len);
632 s->buf_ptr += len;
633 buf1 += len;
634 size -= len;
635 n = (s->buf_ptr - s->buf);
636 /* if buffer full, then send it */
637 if (n >= max_packet_size) {
638 rtp_send_data(s1, s->buf, n, 0);
639 s->buf_ptr = s->buf;
640 /* update timestamp */
641 s->timestamp += n / sample_size;
642 }
643 }
644}
645
646/* NOTE: we suppose that exactly one frame is given as argument here */
647/* XXX: test it */
648static void rtp_send_mpegaudio(AVFormatContext *s1,
649 const uint8_t *buf1, int size)
650{
651 RTPDemuxContext *s = s1->priv_data;
652 AVStream *st = s1->streams[0];
653 int len, count, max_packet_size;
654
655 max_packet_size = s->max_payload_size;
656
657 /* test if we must flush because not enough space */
658 len = (s->buf_ptr - s->buf);
659 if ((len + size) > max_packet_size) {
660 if (len > 4) {
661 rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
662 s->buf_ptr = s->buf + 4;
663 /* 90 KHz time stamp */
664 s->timestamp = s->base_timestamp +
665 (s->cur_timestamp * 90000LL) / st->codec->sample_rate;
666 }
667 }
668
669 /* add the packet */
670 if (size > max_packet_size) {
671 /* big packet: fragment */
672 count = 0;
673 while (size > 0) {
674 len = max_packet_size - 4;
675 if (len > size)
676 len = size;
677 /* build fragmented packet */
678 s->buf[0] = 0;
679 s->buf[1] = 0;
680 s->buf[2] = count >> 8;
681 s->buf[3] = count;
682 memcpy(s->buf + 4, buf1, len);
683 rtp_send_data(s1, s->buf, len + 4, 0);
684 size -= len;
685 buf1 += len;
686 count += len;
687 }
688 } else {
689 if (s->buf_ptr == s->buf + 4) {
690 /* no fragmentation possible */
691 s->buf[0] = 0;
692 s->buf[1] = 0;
693 s->buf[2] = 0;
694 s->buf[3] = 0;
695 }
696 memcpy(s->buf_ptr, buf1, size);
697 s->buf_ptr += size;
698 }
699 s->cur_timestamp += st->codec->frame_size;
700}
701
702/* NOTE: a single frame must be passed with sequence header if
703 needed. XXX: use slices. */
704static void rtp_send_mpegvideo(AVFormatContext *s1,
705 const uint8_t *buf1, int size)
706{
707 RTPDemuxContext *s = s1->priv_data;
708 AVStream *st = s1->streams[0];
709 int len, h, max_packet_size;
710 uint8_t *q;
711
712 max_packet_size = s->max_payload_size;
713
714 while (size > 0) {
715 /* XXX: more correct headers */
716 h = 0;
717 if (st->codec->sub_id == 2)
718 h |= 1 << 26; /* mpeg 2 indicator */
719 q = s->buf;
720 *q++ = h >> 24;
721 *q++ = h >> 16;
722 *q++ = h >> 8;
723 *q++ = h;
724
725 if (st->codec->sub_id == 2) {
726 h = 0;
727 *q++ = h >> 24;
728 *q++ = h >> 16;
729 *q++ = h >> 8;
730 *q++ = h;
731 }
732
733 len = max_packet_size - (q - s->buf);
734 if (len > size)
735 len = size;
736
737 memcpy(q, buf1, len);
738 q += len;
739
740 /* 90 KHz time stamp */
741 s->timestamp = s->base_timestamp +
742 av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
743 rtp_send_data(s1, s->buf, q - s->buf, (len == size));
744
745 buf1 += len;
746 size -= len;
747 }
748 s->cur_timestamp++;
749}
750
751static void rtp_send_raw(AVFormatContext *s1,
752 const uint8_t *buf1, int size)
753{
754 RTPDemuxContext *s = s1->priv_data;
755 AVStream *st = s1->streams[0];
756 int len, max_packet_size;
757
758 max_packet_size = s->max_payload_size;
759
760 while (size > 0) {
761 len = max_packet_size;
762 if (len > size)
763 len = size;
764
765 /* 90 KHz time stamp */
766 s->timestamp = s->base_timestamp +
767 av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
768 rtp_send_data(s1, buf1, len, (len == size));
769
770 buf1 += len;
771 size -= len;
772 }
773 s->cur_timestamp++;
774}
775
776/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
777static void rtp_send_mpegts_raw(AVFormatContext *s1,
778 const uint8_t *buf1, int size)
779{
780 RTPDemuxContext *s = s1->priv_data;
781 int len, out_len;
782
783 while (size >= TS_PACKET_SIZE) {
784 len = s->max_payload_size - (s->buf_ptr - s->buf);
785 if (len > size)
786 len = size;
787 memcpy(s->buf_ptr, buf1, len);
788 buf1 += len;
789 size -= len;
790 s->buf_ptr += len;
791
792 out_len = s->buf_ptr - s->buf;
793 if (out_len >= s->max_payload_size) {
794 rtp_send_data(s1, s->buf, out_len, 0);
795 s->buf_ptr = s->buf;
796 }
797 }
798}
799
800/* write an RTP packet. 'buf1' must contain a single specific frame. */
801static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
802{
803 RTPDemuxContext *s = s1->priv_data;
804 AVStream *st = s1->streams[0];
805 int rtcp_bytes;
806 int64_t ntp_time;
807 int size= pkt->size;
808 uint8_t *buf1= pkt->data;
809
810#ifdef DEBUG
811 printf("%d: write len=%d\n", pkt->stream_index, size);
812#endif
813
814 /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
815 rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
816 RTCP_TX_RATIO_DEN;
817 if (s->first_packet || rtcp_bytes >= 28) {
818 /* compute NTP time */
819 /* XXX: 90 kHz timestamp hardcoded */
820 ntp_time = (pkt->pts << 28) / 5625;
821 rtcp_send_sr(s1, ntp_time);
822 s->last_octet_count = s->octet_count;
823 s->first_packet = 0;
824 }
825
826 switch(st->codec->codec_id) {
827 case CODEC_ID_PCM_MULAW:
828 case CODEC_ID_PCM_ALAW:
829 case CODEC_ID_PCM_U8:
830 case CODEC_ID_PCM_S8:
831 rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
832 break;
833 case CODEC_ID_PCM_U16BE:
834 case CODEC_ID_PCM_U16LE:
835 case CODEC_ID_PCM_S16BE:
836 case CODEC_ID_PCM_S16LE:
837 rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
838 break;
839 case CODEC_ID_MP2:
840 case CODEC_ID_MP3:
841 rtp_send_mpegaudio(s1, buf1, size);
842 break;
843 case CODEC_ID_MPEG1VIDEO:
844 rtp_send_mpegvideo(s1, buf1, size);
845 break;
846 case CODEC_ID_MPEG2TS:
847 rtp_send_mpegts_raw(s1, buf1, size);
848 break;
849 default:
850 /* better than nothing : send the codec raw data */
851 rtp_send_raw(s1, buf1, size);
852 break;
853 }
854 return 0;
855}
856
857static int rtp_write_trailer(AVFormatContext *s1)
858{
859 // RTPDemuxContext *s = s1->priv_data;
860 return 0;
861}
862
863AVOutputFormat rtp_muxer = {
864 "rtp",
865 "RTP output format",
866 NULL,
867 NULL,
868 sizeof(RTPDemuxContext),
869 CODEC_ID_PCM_MULAW,
870 CODEC_ID_NONE,
871 rtp_write_header,
872 rtp_write_packet,
873 rtp_write_trailer,
874};
875
876int rtp_init(void)
877{
878 av_register_output_format(&rtp_muxer);
879 return 0;
880}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette