Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtp.c @ 25f8db58

History | View | Annotate | Download (30.3 KB)

1 e309128f Fabrice Bellard
/*
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 8b1ab7bf Fabrice Bellard
#include "mpegts.h"
21 d1ccf0e0 Romain Degez
#include "bitstream.h"
22 e309128f Fabrice Bellard
23
#include <unistd.h>
24
#include <sys/types.h>
25 b8a78f41 Michael Niedermayer
#include <sys/socket.h>
26 e309128f Fabrice Bellard
#include <netinet/in.h>
27 9ddd71fc Fran├žois Revol
#ifndef __BEOS__
28
# include <arpa/inet.h>
29
#else
30
# include "barpainet.h"
31
#endif
32 e309128f Fabrice Bellard
#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 d1ccf0e0 Romain Degez
/* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
47
AVRtpPayloadType_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
180
AVRtpDynamicPayloadType_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 e309128f Fabrice Bellard
187 8b1ab7bf Fabrice Bellard
struct RTPDemuxContext {
188
    AVFormatContext *ic;
189
    AVStream *st;
190 e309128f Fabrice Bellard
    int payload_type;
191 0c1a9eda Zdenek Kabelac
    uint32_t ssrc;
192
    uint16_t seq;
193
    uint32_t timestamp;
194
    uint32_t base_timestamp;
195
    uint32_t cur_timestamp;
196 e309128f Fabrice Bellard
    int max_payload_size;
197 d1ccf0e0 Romain Degez
    MpegTSContext *ts; /* only used for MP2T payloads */
198 8b1ab7bf Fabrice Bellard
    int read_buf_index;
199
    int read_buf_size;
200
    
201 e309128f Fabrice Bellard
    /* rtcp sender statistics receive */
202 0c1a9eda Zdenek Kabelac
    int64_t last_rtcp_ntp_time;
203 e5526b2c Fabrice Bellard
    int64_t first_rtcp_ntp_time;
204 0c1a9eda Zdenek Kabelac
    uint32_t last_rtcp_timestamp;
205 e309128f Fabrice Bellard
    /* 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 0c1a9eda Zdenek Kabelac
    uint8_t buf[RTP_MAX_PACKET_LENGTH];
212
    uint8_t *buf_ptr;
213 d1ccf0e0 Romain Degez
    /* special infos for au headers parsing */
214
    rtp_payload_data_t *rtp_payload_data;
215 8b1ab7bf Fabrice Bellard
};
216 e309128f Fabrice Bellard
217
int rtp_get_codec_info(AVCodecContext *codec, int payload_type)
218
{
219 d1ccf0e0 Romain Degez
    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_type;
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 e309128f Fabrice Bellard
    }
228 d1ccf0e0 Romain Degez
    return -1;
229 e309128f Fabrice Bellard
}
230
231
/* return < 0 if unknown payload type */
232
int rtp_get_payload_type(AVCodecContext *codec)
233
{
234 d1ccf0e0 Romain Degez
    int i, payload_type;
235 e309128f Fabrice Bellard
236
    /* compute the payload type */
237 d1ccf0e0 Romain Degez
    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 e309128f Fabrice Bellard
        }
244
    return payload_type;
245
}
246
247 0c1a9eda Zdenek Kabelac
static inline uint32_t decode_be32(const uint8_t *p)
248 e309128f Fabrice Bellard
{
249
    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
250
}
251
252 e5526b2c Fabrice Bellard
static inline uint64_t decode_be64(const uint8_t *p)
253 e309128f Fabrice Bellard
{
254 0c1a9eda Zdenek Kabelac
    return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4);
255 e309128f Fabrice Bellard
}
256
257 8b1ab7bf Fabrice Bellard
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
258 e309128f Fabrice Bellard
{
259
    if (buf[1] != 200)
260
        return -1;
261
    s->last_rtcp_ntp_time = decode_be64(buf + 8);
262 e5526b2c Fabrice Bellard
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
263
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
264 e309128f Fabrice Bellard
    s->last_rtcp_timestamp = decode_be32(buf + 16);
265
    return 0;
266
}
267
268
/**
269 8b1ab7bf Fabrice Bellard
 * 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
 */
273 d1ccf0e0 Romain Degez
RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, int payload_type, rtp_payload_data_t *rtp_payload_data)
274 8b1ab7bf Fabrice Bellard
{
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 d1ccf0e0 Romain Degez
    s->rtp_payload_data = rtp_payload_data;
286
    if (!strcmp(AVRtpPayloadTypes[payload_type].enc_name, "MP2T")) {
287 8b1ab7bf Fabrice Bellard
        s->ts = mpegts_parse_open(s->ic);
288
        if (s->ts == NULL) {
289
            av_free(s);
290
            return NULL;
291
        }
292 ccd39ae6 Fabrice Bellard
    } else {
293 01f4895c Michael Niedermayer
        switch(st->codec->codec_id) {
294 ccd39ae6 Fabrice Bellard
        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 8b1ab7bf Fabrice Bellard
    }
305
    return s;
306
}
307
308 d1ccf0e0 Romain Degez
static 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 8b1ab7bf Fabrice Bellard
/**
357
 * Parse an RTP or RTCP packet directly sent as a buffer. 
358
 * @param s RTP parse context.
359 e309128f Fabrice Bellard
 * @param pkt returned packet
360 8b1ab7bf Fabrice Bellard
 * @param buf input buffer or NULL to read the next packets
361 e309128f Fabrice Bellard
 * @param len buffer len
362 8b1ab7bf Fabrice Bellard
 * @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 e309128f Fabrice Bellard
 */
365 8b1ab7bf Fabrice Bellard
int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, 
366
                     const uint8_t *buf, int len)
367 e309128f Fabrice Bellard
{
368
    unsigned int ssrc, h;
369 8b1ab7bf Fabrice Bellard
    int payload_type, seq, delta_timestamp, ret;
370 e309128f Fabrice Bellard
    AVStream *st;
371 0c1a9eda Zdenek Kabelac
    uint32_t timestamp;
372 e309128f Fabrice Bellard
    
373 8b1ab7bf Fabrice Bellard
    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 e309128f Fabrice Bellard
    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 8b1ab7bf Fabrice Bellard
        rtcp_parse_packet(s, buf, len);
395 e309128f Fabrice Bellard
        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
#if defined(DEBUG) || 1
406
    if (seq != ((s->seq + 1) & 0xffff)) {
407 01f4895c Michael Niedermayer
        av_log(s->st->codec, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n", 
408 e309128f Fabrice Bellard
               payload_type, seq, ((s->seq + 1) & 0xffff));
409
    }
410
#endif
411 d1ccf0e0 Romain Degez
    s->seq = seq;
412 e309128f Fabrice Bellard
    len -= 12;
413
    buf += 12;
414 8b1ab7bf Fabrice Bellard
415
    st = s->st;
416
    if (!st) {
417
        /* specific MPEG2TS demux support */
418
        ret = mpegts_parse_packet(s->ts, pkt, buf, len);
419
        if (ret < 0)
420 e309128f Fabrice Bellard
            return -1;
421 8b1ab7bf Fabrice Bellard
        if (ret < len) {
422
            s->read_buf_size = len - ret;
423
            memcpy(s->buf, buf + ret, s->read_buf_size);
424
            s->read_buf_index = 0;
425
            return 1;
426
        }
427
    } else {
428 01f4895c Michael Niedermayer
        switch(st->codec->codec_id) {
429 8b1ab7bf Fabrice Bellard
        case CODEC_ID_MP2:
430
            /* better than nothing: skip mpeg audio RTP header */
431
            if (len <= 4)
432
                return -1;
433
            h = decode_be32(buf);
434
            len -= 4;
435
            buf += 4;
436
            av_new_packet(pkt, len);
437
            memcpy(pkt->data, buf, len);
438
            break;
439
        case CODEC_ID_MPEG1VIDEO:
440 ccd39ae6 Fabrice Bellard
            /* better than nothing: skip mpeg video RTP header */
441 e309128f Fabrice Bellard
            if (len <= 4)
442
                return -1;
443 8b1ab7bf Fabrice Bellard
            h = decode_be32(buf);
444 e309128f Fabrice Bellard
            buf += 4;
445
            len -= 4;
446 8b1ab7bf Fabrice Bellard
            if (h & (1 << 26)) {
447
                /* mpeg2 */
448
                if (len <= 4)
449
                    return -1;
450
                buf += 4;
451
                len -= 4;
452
            }
453
            av_new_packet(pkt, len);
454
            memcpy(pkt->data, buf, len);
455
            break;
456
        default:
457
            av_new_packet(pkt, len);
458
            memcpy(pkt->data, buf, len);
459
            break;
460 e309128f Fabrice Bellard
        }
461 8b1ab7bf Fabrice Bellard
        
462 01f4895c Michael Niedermayer
        switch(st->codec->codec_id) {
463 8b1ab7bf Fabrice Bellard
        case CODEC_ID_MP2:
464
        case CODEC_ID_MPEG1VIDEO:
465
            if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
466
                int64_t addend;
467
                /* XXX: is it really necessary to unify the timestamp base ? */
468
                /* compute pts from timestamp with received ntp_time */
469
                delta_timestamp = timestamp - s->last_rtcp_timestamp;
470
                /* convert to 90 kHz without overflow */
471
                addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14;
472
                addend = (addend * 5625) >> 14;
473
                pkt->pts = addend + delta_timestamp;
474
            }
475
            break;
476 d1ccf0e0 Romain Degez
        case CODEC_ID_MPEG4:
477
            pkt->pts = timestamp;
478
            break;
479
        case CODEC_ID_MPEG4AAC:
480
            if (rtp_parse_mp4_au(s, buf))
481
              return -1;
482 d3655fad Michael Niedermayer
            {
483 d1ccf0e0 Romain Degez
            rtp_payload_data_t *infos = s->rtp_payload_data;
484
            if (infos == NULL)
485
                return -1;
486
            buf += infos->au_headers_length_bytes + 2;
487
            len -= infos->au_headers_length_bytes + 2;
488
489
            /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
490
               one au_header */
491
            av_new_packet(pkt, infos->au_headers[0].size);
492
            memcpy(pkt->data, buf, infos->au_headers[0].size);
493
            buf += infos->au_headers[0].size;
494
            len -= infos->au_headers[0].size;
495 d3655fad Michael Niedermayer
            }
496 d1ccf0e0 Romain Degez
            s->read_buf_size = len;
497
            s->buf_ptr = (char *)buf;
498
            pkt->stream_index = s->st->index;
499
            return 0;
500 8b1ab7bf Fabrice Bellard
        default:
501
            /* no timestamp info yet */
502
            break;
503 e5526b2c Fabrice Bellard
        }
504 8b1ab7bf Fabrice Bellard
        pkt->stream_index = s->st->index;
505 e309128f Fabrice Bellard
    }
506
    return 0;
507
}
508
509 8b1ab7bf Fabrice Bellard
void rtp_parse_close(RTPDemuxContext *s)
510 e309128f Fabrice Bellard
{
511 d1ccf0e0 Romain Degez
    if (!strcmp(AVRtpPayloadTypes[s->payload_type].enc_name, "MP2T")) {
512 8b1ab7bf Fabrice Bellard
        mpegts_parse_close(s->ts);
513 e309128f Fabrice Bellard
    }
514 8b1ab7bf Fabrice Bellard
    av_free(s);
515 e309128f Fabrice Bellard
}
516
517
/* rtp output */
518
519
static int rtp_write_header(AVFormatContext *s1)
520
{
521 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
522
    int payload_type, max_packet_size, n;
523 e309128f Fabrice Bellard
    AVStream *st;
524
525
    if (s1->nb_streams != 1)
526
        return -1;
527
    st = s1->streams[0];
528
529 01f4895c Michael Niedermayer
    payload_type = rtp_get_payload_type(st->codec);
530 e309128f Fabrice Bellard
    if (payload_type < 0)
531 65e70450 Fabrice Bellard
        payload_type = RTP_PT_PRIVATE; /* private payload type */
532 e309128f Fabrice Bellard
    s->payload_type = payload_type;
533
534
    s->base_timestamp = random();
535
    s->timestamp = s->base_timestamp;
536
    s->ssrc = random();
537
    s->first_packet = 1;
538
539
    max_packet_size = url_fget_max_packet_size(&s1->pb);
540
    if (max_packet_size <= 12)
541
        return AVERROR_IO;
542
    s->max_payload_size = max_packet_size - 12;
543
544 01f4895c Michael Niedermayer
    switch(st->codec->codec_id) {
545 e309128f Fabrice Bellard
    case CODEC_ID_MP2:
546 80783dc2 Fabrice Bellard
    case CODEC_ID_MP3:
547 e309128f Fabrice Bellard
        s->buf_ptr = s->buf + 4;
548
        s->cur_timestamp = 0;
549
        break;
550
    case CODEC_ID_MPEG1VIDEO:
551
        s->cur_timestamp = 0;
552
        break;
553 8b1ab7bf Fabrice Bellard
    case CODEC_ID_MPEG2TS:
554
        n = s->max_payload_size / TS_PACKET_SIZE;
555
        if (n < 1)
556
            n = 1;
557
        s->max_payload_size = n * TS_PACKET_SIZE;
558
        s->buf_ptr = s->buf;
559
        break;
560 e309128f Fabrice Bellard
    default:
561
        s->buf_ptr = s->buf;
562
        break;
563
    }
564
565
    return 0;
566
}
567
568
/* send an rtcp sender report packet */
569 0c1a9eda Zdenek Kabelac
static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
570 e309128f Fabrice Bellard
{
571 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
572 e309128f Fabrice Bellard
#if defined(DEBUG)
573
    printf("RTCP: %02x %Lx %x\n", s->payload_type, ntp_time, s->timestamp);
574
#endif
575
    put_byte(&s1->pb, (RTP_VERSION << 6));
576
    put_byte(&s1->pb, 200);
577
    put_be16(&s1->pb, 6); /* length in words - 1 */
578
    put_be32(&s1->pb, s->ssrc);
579
    put_be64(&s1->pb, ntp_time);
580
    put_be32(&s1->pb, s->timestamp);
581
    put_be32(&s1->pb, s->packet_count);
582
    put_be32(&s1->pb, s->octet_count);
583
    put_flush_packet(&s1->pb);
584
}
585
586
/* send an rtp packet. sequence number is incremented, but the caller
587
   must update the timestamp itself */
588 00364063 Luca Abeni
static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
589 e309128f Fabrice Bellard
{
590 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
591 e309128f Fabrice Bellard
592
#ifdef DEBUG
593
    printf("rtp_send_data size=%d\n", len);
594
#endif
595
596
    /* build the RTP header */
597
    put_byte(&s1->pb, (RTP_VERSION << 6));
598 00364063 Luca Abeni
    put_byte(&s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
599 e309128f Fabrice Bellard
    put_be16(&s1->pb, s->seq);
600
    put_be32(&s1->pb, s->timestamp);
601
    put_be32(&s1->pb, s->ssrc);
602
    
603
    put_buffer(&s1->pb, buf1, len);
604
    put_flush_packet(&s1->pb);
605
    
606
    s->seq++;
607
    s->octet_count += len;
608
    s->packet_count++;
609
}
610
611
/* send an integer number of samples and compute time stamp and fill
612
   the rtp send buffer before sending. */
613
static void rtp_send_samples(AVFormatContext *s1,
614 49057904 Fabrice Bellard
                             const uint8_t *buf1, int size, int sample_size)
615 e309128f Fabrice Bellard
{
616 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
617 e309128f Fabrice Bellard
    int len, max_packet_size, n;
618
619
    max_packet_size = (s->max_payload_size / sample_size) * sample_size;
620
    /* not needed, but who nows */
621
    if ((size % sample_size) != 0)
622
        av_abort();
623
    while (size > 0) {
624
        len = (max_packet_size - (s->buf_ptr - s->buf));
625
        if (len > size)
626
            len = size;
627
628
        /* copy data */
629
        memcpy(s->buf_ptr, buf1, len);
630
        s->buf_ptr += len;
631
        buf1 += len;
632
        size -= len;
633
        n = (s->buf_ptr - s->buf);
634
        /* if buffer full, then send it */
635
        if (n >= max_packet_size) {
636 00364063 Luca Abeni
            rtp_send_data(s1, s->buf, n, 0);
637 e309128f Fabrice Bellard
            s->buf_ptr = s->buf;
638
            /* update timestamp */
639
            s->timestamp += n / sample_size;
640
        }
641
    }
642
} 
643
644
/* NOTE: we suppose that exactly one frame is given as argument here */
645
/* XXX: test it */
646
static void rtp_send_mpegaudio(AVFormatContext *s1,
647 49057904 Fabrice Bellard
                               const uint8_t *buf1, int size)
648 e309128f Fabrice Bellard
{
649 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
650 e309128f Fabrice Bellard
    AVStream *st = s1->streams[0];
651
    int len, count, max_packet_size;
652
653
    max_packet_size = s->max_payload_size;
654
655
    /* test if we must flush because not enough space */
656
    len = (s->buf_ptr - s->buf);
657
    if ((len + size) > max_packet_size) {
658
        if (len > 4) {
659 00364063 Luca Abeni
            rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
660 e309128f Fabrice Bellard
            s->buf_ptr = s->buf + 4;
661
            /* 90 KHz time stamp */
662
            s->timestamp = s->base_timestamp + 
663 01f4895c Michael Niedermayer
                (s->cur_timestamp * 90000LL) / st->codec->sample_rate;
664 e309128f Fabrice Bellard
        }
665
    }
666
667
    /* add the packet */
668
    if (size > max_packet_size) {
669
        /* big packet: fragment */
670
        count = 0;
671
        while (size > 0) {
672
            len = max_packet_size - 4;
673
            if (len > size)
674
                len = size;
675
            /* build fragmented packet */
676
            s->buf[0] = 0;
677
            s->buf[1] = 0;
678
            s->buf[2] = count >> 8;
679
            s->buf[3] = count;
680
            memcpy(s->buf + 4, buf1, len);
681 00364063 Luca Abeni
            rtp_send_data(s1, s->buf, len + 4, 0);
682 e309128f Fabrice Bellard
            size -= len;
683
            buf1 += len;
684
            count += len;
685
        }
686
    } else {
687
        if (s->buf_ptr == s->buf + 4) {
688
            /* no fragmentation possible */
689
            s->buf[0] = 0;
690
            s->buf[1] = 0;
691
            s->buf[2] = 0;
692
            s->buf[3] = 0;
693
        }
694
        memcpy(s->buf_ptr, buf1, size);
695
        s->buf_ptr += size;
696
    }
697 01f4895c Michael Niedermayer
    s->cur_timestamp += st->codec->frame_size;
698 e309128f Fabrice Bellard
}
699
700
/* NOTE: a single frame must be passed with sequence header if
701
   needed. XXX: use slices. */
702
static void rtp_send_mpegvideo(AVFormatContext *s1,
703 49057904 Fabrice Bellard
                               const uint8_t *buf1, int size)
704 e309128f Fabrice Bellard
{
705 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
706 e309128f Fabrice Bellard
    AVStream *st = s1->streams[0];
707
    int len, h, max_packet_size;
708 0c1a9eda Zdenek Kabelac
    uint8_t *q;
709 e309128f Fabrice Bellard
710
    max_packet_size = s->max_payload_size;
711
712
    while (size > 0) {
713
        /* XXX: more correct headers */
714
        h = 0;
715 01f4895c Michael Niedermayer
        if (st->codec->sub_id == 2)
716 e309128f Fabrice Bellard
            h |= 1 << 26; /* mpeg 2 indicator */
717
        q = s->buf;
718
        *q++ = h >> 24;
719
        *q++ = h >> 16;
720
        *q++ = h >> 8;
721
        *q++ = h;
722
723 01f4895c Michael Niedermayer
        if (st->codec->sub_id == 2) {
724 e309128f Fabrice Bellard
            h = 0;
725
            *q++ = h >> 24;
726
            *q++ = h >> 16;
727
            *q++ = h >> 8;
728
            *q++ = h;
729
        }
730
        
731
        len = max_packet_size - (q - s->buf);
732
        if (len > size)
733
            len = size;
734
735
        memcpy(q, buf1, len);
736
        q += len;
737
738
        /* 90 KHz time stamp */
739
        s->timestamp = s->base_timestamp + 
740 01f4895c Michael Niedermayer
            av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
741 760fb54f Michael Niedermayer
        rtp_send_data(s1, s->buf, q - s->buf, (len == size));
742 e309128f Fabrice Bellard
743
        buf1 += len;
744
        size -= len;
745
    }
746
    s->cur_timestamp++;
747
}
748
749 65e70450 Fabrice Bellard
static void rtp_send_raw(AVFormatContext *s1,
750 49057904 Fabrice Bellard
                         const uint8_t *buf1, int size)
751 65e70450 Fabrice Bellard
{
752 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
753 65e70450 Fabrice Bellard
    AVStream *st = s1->streams[0];
754
    int len, max_packet_size;
755
756
    max_packet_size = s->max_payload_size;
757
758
    while (size > 0) {
759
        len = max_packet_size;
760
        if (len > size)
761
            len = size;
762
763
        /* 90 KHz time stamp */
764
        s->timestamp = s->base_timestamp + 
765 01f4895c Michael Niedermayer
            av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
766 00364063 Luca Abeni
        rtp_send_data(s1, buf1, len, (len == size));
767 65e70450 Fabrice Bellard
768
        buf1 += len;
769
        size -= len;
770
    }
771
    s->cur_timestamp++;
772
}
773
774 8b1ab7bf Fabrice Bellard
/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
775
static void rtp_send_mpegts_raw(AVFormatContext *s1,
776
                                const uint8_t *buf1, int size)
777
{
778
    RTPDemuxContext *s = s1->priv_data;
779
    int len, out_len;
780
781
    while (size >= TS_PACKET_SIZE) {
782
        len = s->max_payload_size - (s->buf_ptr - s->buf);
783
        if (len > size)
784
            len = size;
785
        memcpy(s->buf_ptr, buf1, len);
786
        buf1 += len;
787
        size -= len;
788
        s->buf_ptr += len;
789
        
790
        out_len = s->buf_ptr - s->buf;
791
        if (out_len >= s->max_payload_size) {
792 00364063 Luca Abeni
            rtp_send_data(s1, s->buf, out_len, 0);
793 8b1ab7bf Fabrice Bellard
            s->buf_ptr = s->buf;
794
        }
795
    }
796
}
797
798 e309128f Fabrice Bellard
/* write an RTP packet. 'buf1' must contain a single specific frame. */
799 e928649b Michael Niedermayer
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
800 e309128f Fabrice Bellard
{
801 8b1ab7bf Fabrice Bellard
    RTPDemuxContext *s = s1->priv_data;
802 e309128f Fabrice Bellard
    AVStream *st = s1->streams[0];
803
    int rtcp_bytes;
804 0c1a9eda Zdenek Kabelac
    int64_t ntp_time;
805 e928649b Michael Niedermayer
    int size= pkt->size;
806
    uint8_t *buf1= pkt->data;
807 e309128f Fabrice Bellard
    
808
#ifdef DEBUG
809 e928649b Michael Niedermayer
    printf("%d: write len=%d\n", pkt->stream_index, size);
810 e309128f Fabrice Bellard
#endif
811
812
    /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
813
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / 
814
        RTCP_TX_RATIO_DEN;
815
    if (s->first_packet || rtcp_bytes >= 28) {
816
        /* compute NTP time */
817 e5526b2c Fabrice Bellard
        /* XXX: 90 kHz timestamp hardcoded */
818 e928649b Michael Niedermayer
        ntp_time = (pkt->pts << 28) / 5625;
819 e309128f Fabrice Bellard
        rtcp_send_sr(s1, ntp_time); 
820
        s->last_octet_count = s->octet_count;
821
        s->first_packet = 0;
822
    }
823
824 01f4895c Michael Niedermayer
    switch(st->codec->codec_id) {
825 e309128f Fabrice Bellard
    case CODEC_ID_PCM_MULAW:
826
    case CODEC_ID_PCM_ALAW:
827
    case CODEC_ID_PCM_U8:
828
    case CODEC_ID_PCM_S8:
829 01f4895c Michael Niedermayer
        rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
830 e309128f Fabrice Bellard
        break;
831
    case CODEC_ID_PCM_U16BE:
832
    case CODEC_ID_PCM_U16LE:
833
    case CODEC_ID_PCM_S16BE:
834
    case CODEC_ID_PCM_S16LE:
835 01f4895c Michael Niedermayer
        rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
836 e309128f Fabrice Bellard
        break;
837
    case CODEC_ID_MP2:
838 80783dc2 Fabrice Bellard
    case CODEC_ID_MP3:
839 e309128f Fabrice Bellard
        rtp_send_mpegaudio(s1, buf1, size);
840
        break;
841
    case CODEC_ID_MPEG1VIDEO:
842
        rtp_send_mpegvideo(s1, buf1, size);
843
        break;
844 8b1ab7bf Fabrice Bellard
    case CODEC_ID_MPEG2TS:
845
        rtp_send_mpegts_raw(s1, buf1, size);
846
        break;
847 e309128f Fabrice Bellard
    default:
848 65e70450 Fabrice Bellard
        /* better than nothing : send the codec raw data */
849
        rtp_send_raw(s1, buf1, size);
850
        break;
851 e309128f Fabrice Bellard
    }
852
    return 0;
853
}
854
855
static int rtp_write_trailer(AVFormatContext *s1)
856
{
857 8b1ab7bf Fabrice Bellard
    //    RTPDemuxContext *s = s1->priv_data;
858 e309128f Fabrice Bellard
    return 0;
859
}
860
861
AVOutputFormat rtp_mux = {
862
    "rtp",
863
    "RTP output format",
864
    NULL,
865
    NULL,
866 8b1ab7bf Fabrice Bellard
    sizeof(RTPDemuxContext),
867 e309128f Fabrice Bellard
    CODEC_ID_PCM_MULAW,
868
    CODEC_ID_NONE,
869
    rtp_write_header,
870
    rtp_write_packet,
871
    rtp_write_trailer,
872
};
873
874
int rtp_init(void)
875
{
876
    av_register_output_format(&rtp_mux);
877
    return 0;
878
}