Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtp.c @ 0d9f8633

History | View | Annotate | Download (38 KB)

1
/*
2
 * RTP input/output format
3
 * Copyright (c) 2002 Fabrice Bellard.
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
#include "avformat.h"
22
#include "mpegts.h"
23
#include "bitstream.h"
24

    
25
#include <unistd.h>
26
#include "network.h"
27

    
28
#include "rtp_internal.h"
29
#include "rtp_h264.h"
30

    
31
//#define DEBUG
32

    
33

    
34
/* TODO: - add RTCP statistics reporting (should be optional).
35

36
         - add support for h263/mpeg4 packetized output : IDEA: send a
37
         buffer to 'rtp_write_packet' contains all the packets for ONE
38
         frame. Each packet should have a four byte header containing
39
         the length in big endian format (same trick as
40
         'url_open_dyn_packet_buf')
41
*/
42

    
43
/* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
44
AVRtpPayloadType_t AVRtpPayloadTypes[]=
45
{
46
  {0, "PCMU",        CODEC_TYPE_AUDIO,   CODEC_ID_PCM_MULAW, 8000, 1},
47
  {1, "Reserved",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
48
  {2, "Reserved",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
49
  {3, "GSM",         CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
50
  {4, "G723",        CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
51
  {5, "DVI4",        CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
52
  {6, "DVI4",        CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 16000, 1},
53
  {7, "LPC",         CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
54
  {8, "PCMA",        CODEC_TYPE_AUDIO,   CODEC_ID_PCM_ALAW, 8000, 1},
55
  {9, "G722",        CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
56
  {10, "L16",        CODEC_TYPE_AUDIO,   CODEC_ID_PCM_S16BE, 44100, 2},
57
  {11, "L16",        CODEC_TYPE_AUDIO,   CODEC_ID_PCM_S16BE, 44100, 1},
58
  {12, "QCELP",      CODEC_TYPE_AUDIO,   CODEC_ID_QCELP, 8000, 1},
59
  {13, "CN",         CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
60
  {14, "MPA",        CODEC_TYPE_AUDIO,   CODEC_ID_MP2, 90000, -1},
61
  {15, "G728",       CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
62
  {16, "DVI4",       CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 11025, 1},
63
  {17, "DVI4",       CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 22050, 1},
64
  {18, "G729",       CODEC_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
65
  {19, "reserved",   CODEC_TYPE_AUDIO,   CODEC_ID_NONE, -1, -1},
66
  {20, "unassigned", CODEC_TYPE_AUDIO,   CODEC_ID_NONE, -1, -1},
67
  {21, "unassigned", CODEC_TYPE_AUDIO,   CODEC_ID_NONE, -1, -1},
68
  {22, "unassigned", CODEC_TYPE_AUDIO,   CODEC_ID_NONE, -1, -1},
69
  {23, "unassigned", CODEC_TYPE_AUDIO,   CODEC_ID_NONE, -1, -1},
70
  {24, "unassigned", CODEC_TYPE_VIDEO,   CODEC_ID_NONE, -1, -1},
71
  {25, "CelB",       CODEC_TYPE_VIDEO,   CODEC_ID_NONE, 90000, -1},
72
  {26, "JPEG",       CODEC_TYPE_VIDEO,   CODEC_ID_MJPEG, 90000, -1},
73
  {27, "unassigned", CODEC_TYPE_VIDEO,   CODEC_ID_NONE, -1, -1},
74
  {28, "nv",         CODEC_TYPE_VIDEO,   CODEC_ID_NONE, 90000, -1},
75
  {29, "unassigned", CODEC_TYPE_VIDEO,   CODEC_ID_NONE, -1, -1},
76
  {30, "unassigned", CODEC_TYPE_VIDEO,   CODEC_ID_NONE, -1, -1},
77
  {31, "H261",       CODEC_TYPE_VIDEO,   CODEC_ID_H261, 90000, -1},
78
  {32, "MPV",        CODEC_TYPE_VIDEO,   CODEC_ID_MPEG1VIDEO, 90000, -1},
79
  {33, "MP2T",       CODEC_TYPE_DATA,    CODEC_ID_MPEG2TS, 90000, -1},
80
  {34, "H263",       CODEC_TYPE_VIDEO,   CODEC_ID_H263, 90000, -1},
81
  {35, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
82
  {36, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
83
  {37, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
84
  {38, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
85
  {39, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
86
  {40, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
87
  {41, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
88
  {42, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
89
  {43, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
90
  {44, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
91
  {45, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
92
  {46, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
93
  {47, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
94
  {48, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
95
  {49, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
96
  {50, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
97
  {51, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
98
  {52, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
99
  {53, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
100
  {54, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
101
  {55, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
102
  {56, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
103
  {57, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
104
  {58, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
105
  {59, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
106
  {60, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
107
  {61, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
108
  {62, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
109
  {63, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
110
  {64, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
111
  {65, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
112
  {66, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
113
  {67, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
114
  {68, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
115
  {69, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
116
  {70, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
117
  {71, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
118
  {72, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
119
  {73, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
120
  {74, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
121
  {75, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
122
  {76, "reserved for RTCP conflict avoidance", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
123
  {77, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
124
  {78, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
125
  {79, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
126
  {80, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
127
  {81, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
128
  {82, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
129
  {83, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
130
  {84, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
131
  {85, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
132
  {86, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
133
  {87, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
134
  {88, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
135
  {89, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
136
  {90, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
137
  {91, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
138
  {92, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
139
  {93, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
140
  {94, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
141
  {95, "unassigned", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
142
  {96, "dynamic",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
143
  {97, "dynamic",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
144
  {98, "dynamic",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
145
  {99, "dynamic",    CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
146
  {100, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
147
  {101, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
148
  {102, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
149
  {103, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
150
  {104, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
151
  {105, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
152
  {106, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
153
  {107, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
154
  {108, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
155
  {109, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
156
  {110, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
157
  {111, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
158
  {112, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
159
  {113, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
160
  {114, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
161
  {115, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
162
  {116, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
163
  {117, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
164
  {118, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
165
  {119, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
166
  {120, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
167
  {121, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
168
  {122, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
169
  {123, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
170
  {124, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
171
  {125, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
172
  {126, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
173
  {127, "dynamic",   CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1},
174
  {-1, "",           CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1}
175
};
176

    
177
/* statistics functions */
178
RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL;
179

    
180
static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4};
181
static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_AAC};
182

    
183
static void register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
184
{
185
    handler->next= RTPFirstDynamicPayloadHandler;
186
    RTPFirstDynamicPayloadHandler= handler;
187
}
188

    
189
void av_register_rtp_dynamic_payload_handlers()
190
{
191
    register_dynamic_payload_handler(&mp4v_es_handler);
192
    register_dynamic_payload_handler(&mpeg4_generic_handler);
193
    register_dynamic_payload_handler(&ff_h264_dynamic_handler);
194
}
195

    
196
int rtp_get_codec_info(AVCodecContext *codec, int payload_type)
197
{
198
    if (AVRtpPayloadTypes[payload_type].codec_id != CODEC_ID_NONE) {
199
        codec->codec_type = AVRtpPayloadTypes[payload_type].codec_type;
200
        codec->codec_id = AVRtpPayloadTypes[payload_type].codec_id;
201
        if (AVRtpPayloadTypes[payload_type].audio_channels > 0)
202
            codec->channels = AVRtpPayloadTypes[payload_type].audio_channels;
203
        if (AVRtpPayloadTypes[payload_type].clock_rate > 0)
204
            codec->sample_rate = AVRtpPayloadTypes[payload_type].clock_rate;
205
        return 0;
206
    }
207
    return -1;
208
}
209

    
210
/* return < 0 if unknown payload type */
211
int rtp_get_payload_type(AVCodecContext *codec)
212
{
213
    int i, payload_type;
214

    
215
    /* compute the payload type */
216
    for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
217
        if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
218
            if (codec->codec_id == CODEC_ID_PCM_S16BE)
219
                if (codec->channels != AVRtpPayloadTypes[i].audio_channels)
220
                    continue;
221
            payload_type = AVRtpPayloadTypes[i].pt;
222
        }
223
    return payload_type;
224
}
225

    
226
static inline uint32_t decode_be32(const uint8_t *p)
227
{
228
    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
229
}
230

    
231
static inline uint64_t decode_be64(const uint8_t *p)
232
{
233
    return ((uint64_t)decode_be32(p) << 32) | decode_be32(p + 4);
234
}
235

    
236
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
237
{
238
    if (buf[1] != 200)
239
        return -1;
240
    s->last_rtcp_ntp_time = decode_be64(buf + 8);
241
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
242
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
243
    s->last_rtcp_timestamp = decode_be32(buf + 16);
244
    return 0;
245
}
246

    
247
#define RTP_SEQ_MOD (1<<16)
248

    
249
/**
250
* called on parse open packet
251
*/
252
static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // called on parse open packet.
253
{
254
    memset(s, 0, sizeof(RTPStatistics));
255
    s->max_seq= base_sequence;
256
    s->probation= 1;
257
}
258

    
259
/**
260
* called whenever there is a large jump in sequence numbers, or when they get out of probation...
261
*/
262
static void rtp_init_sequence(RTPStatistics *s, uint16_t seq)
263
{
264
    s->max_seq= seq;
265
    s->cycles= 0;
266
    s->base_seq= seq -1;
267
    s->bad_seq= RTP_SEQ_MOD + 1;
268
    s->received= 0;
269
    s->expected_prior= 0;
270
    s->received_prior= 0;
271
    s->jitter= 0;
272
    s->transit= 0;
273
}
274

    
275
/**
276
* returns 1 if we should handle this packet.
277
*/
278
static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
279
{
280
    uint16_t udelta= seq - s->max_seq;
281
    const int MAX_DROPOUT= 3000;
282
    const int MAX_MISORDER = 100;
283
    const int MIN_SEQUENTIAL = 2;
284

    
285
    /* source not valid until MIN_SEQUENTIAL packets with sequence seq. numbers have been received */
286
    if(s->probation)
287
    {
288
        if(seq==s->max_seq + 1) {
289
            s->probation--;
290
            s->max_seq= seq;
291
            if(s->probation==0) {
292
                rtp_init_sequence(s, seq);
293
                s->received++;
294
                return 1;
295
            }
296
        } else {
297
            s->probation= MIN_SEQUENTIAL - 1;
298
            s->max_seq = seq;
299
        }
300
    } else if (udelta < MAX_DROPOUT) {
301
        // in order, with permissible gap
302
        if(seq < s->max_seq) {
303
            //sequence number wrapped; count antother 64k cycles
304
            s->cycles += RTP_SEQ_MOD;
305
        }
306
        s->max_seq= seq;
307
    } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
308
        // sequence made a large jump...
309
        if(seq==s->bad_seq) {
310
            // two sequential packets-- assume that the other side restarted without telling us; just resync.
311
            rtp_init_sequence(s, seq);
312
        } else {
313
            s->bad_seq= (seq + 1) & (RTP_SEQ_MOD-1);
314
            return 0;
315
        }
316
    } else {
317
        // duplicate or reordered packet...
318
    }
319
    s->received++;
320
    return 1;
321
}
322

    
323
#if 0
324
/**
325
* This function is currently unused; without a valid local ntp time, I don't see how we could calculate the
326
* difference between the arrival and sent timestamp.  As a result, the jitter and transit statistics values
327
* never change.  I left this in in case someone else can see a way. (rdm)
328
*/
329
static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp)
330
{
331
    uint32_t transit= arrival_timestamp - sent_timestamp;
332
    int d;
333
    s->transit= transit;
334
    d= FFABS(transit - s->transit);
335
    s->jitter += d - ((s->jitter + 8)>>4);
336
}
337
#endif
338

    
339
/**
340
 * some rtp servers assume client is dead if they don't hear from them...
341
 * so we send a Receiver Report to the provided ByteIO context
342
 * (we don't have access to the rtcp handle from here)
343
 */
344
int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
345
{
346
    ByteIOContext pb;
347
    uint8_t *buf;
348
    int len;
349
    int rtcp_bytes;
350
    RTPStatistics *stats= &s->statistics;
351
    uint32_t lost;
352
    uint32_t extended_max;
353
    uint32_t expected_interval;
354
    uint32_t received_interval;
355
    uint32_t lost_interval;
356
    uint32_t expected;
357
    uint32_t fraction;
358
    uint64_t ntp_time= s->last_rtcp_ntp_time; // TODO: Get local ntp time?
359

    
360
    if (!s->rtp_ctx || (count < 1))
361
        return -1;
362

    
363
    /* TODO: I think this is way too often; RFC 1889 has algorithm for this */
364
    /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
365
    s->octet_count += count;
366
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
367
        RTCP_TX_RATIO_DEN;
368
    rtcp_bytes /= 50; // mmu_man: that's enough for me... VLC sends much less btw !?
369
    if (rtcp_bytes < 28)
370
        return -1;
371
    s->last_octet_count = s->octet_count;
372

    
373
    if (url_open_dyn_buf(&pb) < 0)
374
        return -1;
375

    
376
    // Receiver Report
377
    put_byte(&pb, (RTP_VERSION << 6) + 1); /* 1 report block */
378
    put_byte(&pb, 201);
379
    put_be16(&pb, 7); /* length in words - 1 */
380
    put_be32(&pb, s->ssrc); // our own SSRC
381
    put_be32(&pb, s->ssrc); // XXX: should be the server's here!
382
    // some placeholders we should really fill...
383
    // RFC 1889/p64
384
    extended_max= stats->cycles + stats->max_seq;
385
    expected= extended_max - stats->base_seq + 1;
386
    lost= expected - stats->received;
387
    lost= FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
388
    expected_interval= expected - stats->expected_prior;
389
    stats->expected_prior= expected;
390
    received_interval= stats->received - stats->received_prior;
391
    stats->received_prior= stats->received;
392
    lost_interval= expected_interval - received_interval;
393
    if (expected_interval==0 || lost_interval<=0) fraction= 0;
394
    else fraction = (lost_interval<<8)/expected_interval;
395

    
396
    fraction= (fraction<<24) | lost;
397

    
398
    put_be32(&pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */
399
    put_be32(&pb, extended_max); /* max sequence received */
400
    put_be32(&pb, stats->jitter>>4); /* jitter */
401

    
402
    if(s->last_rtcp_ntp_time==AV_NOPTS_VALUE)
403
    {
404
        put_be32(&pb, 0); /* last SR timestamp */
405
        put_be32(&pb, 0); /* delay since last SR */
406
    } else {
407
        uint32_t middle_32_bits= s->last_rtcp_ntp_time>>16; // this is valid, right? do we need to handle 64 bit values special?
408
        uint32_t delay_since_last= ntp_time - s->last_rtcp_ntp_time;
409

    
410
        put_be32(&pb, middle_32_bits); /* last SR timestamp */
411
        put_be32(&pb, delay_since_last); /* delay since last SR */
412
    }
413

    
414
    // CNAME
415
    put_byte(&pb, (RTP_VERSION << 6) + 1); /* 1 report block */
416
    put_byte(&pb, 202);
417
    len = strlen(s->hostname);
418
    put_be16(&pb, (6 + len + 3) / 4); /* length in words - 1 */
419
    put_be32(&pb, s->ssrc);
420
    put_byte(&pb, 0x01);
421
    put_byte(&pb, len);
422
    put_buffer(&pb, s->hostname, len);
423
    // padding
424
    for (len = (6 + len) % 4; len % 4; len++) {
425
        put_byte(&pb, 0);
426
    }
427

    
428
    put_flush_packet(&pb);
429
    len = url_close_dyn_buf(&pb, &buf);
430
    if ((len > 0) && buf) {
431
        int result;
432
#if defined(DEBUG)
433
        printf("sending %d bytes of RR\n", len);
434
#endif
435
        result= url_write(s->rtp_ctx, buf, len);
436
#if defined(DEBUG)
437
        printf("result from url_write: %d\n", result);
438
#endif
439
        av_free(buf);
440
    }
441
    return 0;
442
}
443

    
444
/**
445
 * open a new RTP parse context for stream 'st'. 'st' can be NULL for
446
 * MPEG2TS streams to indicate that they should be demuxed inside the
447
 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
448
 * TODO: change this to not take rtp_payload data, and use the new dynamic payload system.
449
 */
450
RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, rtp_payload_data_t *rtp_payload_data)
451
{
452
    RTPDemuxContext *s;
453

    
454
    s = av_mallocz(sizeof(RTPDemuxContext));
455
    if (!s)
456
        return NULL;
457
    s->payload_type = payload_type;
458
    s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
459
    s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
460
    s->ic = s1;
461
    s->st = st;
462
    s->rtp_payload_data = rtp_payload_data;
463
    rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?
464
    if (!strcmp(AVRtpPayloadTypes[payload_type].enc_name, "MP2T")) {
465
        s->ts = mpegts_parse_open(s->ic);
466
        if (s->ts == NULL) {
467
            av_free(s);
468
            return NULL;
469
        }
470
    } else {
471
        switch(st->codec->codec_id) {
472
        case CODEC_ID_MPEG1VIDEO:
473
        case CODEC_ID_MPEG2VIDEO:
474
        case CODEC_ID_MP2:
475
        case CODEC_ID_MP3:
476
        case CODEC_ID_MPEG4:
477
        case CODEC_ID_H264:
478
            st->need_parsing = 1;
479
            break;
480
        default:
481
            break;
482
        }
483
    }
484
    // needed to send back RTCP RR in RTSP sessions
485
    s->rtp_ctx = rtpc;
486
    gethostname(s->hostname, sizeof(s->hostname));
487
    return s;
488
}
489

    
490
static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf)
491
{
492
    int au_headers_length, au_header_size, i;
493
    GetBitContext getbitcontext;
494
    rtp_payload_data_t *infos;
495

    
496
    infos = s->rtp_payload_data;
497

    
498
    if (infos == NULL)
499
        return -1;
500

    
501
    /* decode the first 2 bytes where are stored the AUHeader sections
502
       length in bits */
503
    au_headers_length = AV_RB16(buf);
504

    
505
    if (au_headers_length > RTP_MAX_PACKET_LENGTH)
506
      return -1;
507

    
508
    infos->au_headers_length_bytes = (au_headers_length + 7) / 8;
509

    
510
    /* skip AU headers length section (2 bytes) */
511
    buf += 2;
512

    
513
    init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8);
514

    
515
    /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
516
    au_header_size = infos->sizelength + infos->indexlength;
517
    if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
518
        return -1;
519

    
520
    infos->nb_au_headers = au_headers_length / au_header_size;
521
    infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers);
522

    
523
    /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
524
       In my test, the faad decoder doesnt behave correctly when sending each AU one by one
525
       but does when sending the whole as one big packet...  */
526
    infos->au_headers[0].size = 0;
527
    infos->au_headers[0].index = 0;
528
    for (i = 0; i < infos->nb_au_headers; ++i) {
529
        infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength);
530
        infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength);
531
    }
532

    
533
    infos->nb_au_headers = 1;
534

    
535
    return 0;
536
}
537

    
538
/**
539
 * This was the second switch in rtp_parse packet.  Normalizes time, if required, sets stream_index, etc.
540
 */
541
static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
542
{
543
    switch(s->st->codec->codec_id) {
544
        case CODEC_ID_MP2:
545
        case CODEC_ID_MPEG1VIDEO:
546
            if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
547
                int64_t addend;
548

    
549
                int delta_timestamp;
550
                /* XXX: is it really necessary to unify the timestamp base ? */
551
                /* compute pts from timestamp with received ntp_time */
552
                delta_timestamp = timestamp - s->last_rtcp_timestamp;
553
                /* convert to 90 kHz without overflow */
554
                addend = (s->last_rtcp_ntp_time - s->first_rtcp_ntp_time) >> 14;
555
                addend = (addend * 5625) >> 14;
556
                pkt->pts = addend + delta_timestamp;
557
            }
558
            break;
559
        case CODEC_ID_AAC:
560
        case CODEC_ID_H264:
561
        case CODEC_ID_MPEG4:
562
            pkt->pts = timestamp;
563
            break;
564
        default:
565
            /* no timestamp info yet */
566
            break;
567
    }
568
    pkt->stream_index = s->st->index;
569
}
570

    
571
/**
572
 * Parse an RTP or RTCP packet directly sent as a buffer.
573
 * @param s RTP parse context.
574
 * @param pkt returned packet
575
 * @param buf input buffer or NULL to read the next packets
576
 * @param len buffer len
577
 * @return 0 if a packet is returned, 1 if a packet is returned and more can follow
578
 * (use buf as NULL to read the next). -1 if no packet (error or no more packet).
579
 */
580
int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
581
                     const uint8_t *buf, int len)
582
{
583
    unsigned int ssrc, h;
584
    int payload_type, seq, ret;
585
    AVStream *st;
586
    uint32_t timestamp;
587
    int rv= 0;
588

    
589
    if (!buf) {
590
        /* return the next packets, if any */
591
        if(s->st && s->parse_packet) {
592
            timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
593
            rv= s->parse_packet(s, pkt, &timestamp, NULL, 0);
594
            finalize_packet(s, pkt, timestamp);
595
            return rv;
596
        } else {
597
            // TODO: Move to a dynamic packet handler (like above)
598
            if (s->read_buf_index >= s->read_buf_size)
599
                return -1;
600
            ret = mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
601
                                      s->read_buf_size - s->read_buf_index);
602
            if (ret < 0)
603
                return -1;
604
            s->read_buf_index += ret;
605
            if (s->read_buf_index < s->read_buf_size)
606
                return 1;
607
            else
608
                return 0;
609
        }
610
    }
611

    
612
    if (len < 12)
613
        return -1;
614

    
615
    if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
616
        return -1;
617
    if (buf[1] >= 200 && buf[1] <= 204) {
618
        rtcp_parse_packet(s, buf, len);
619
        return -1;
620
    }
621
    payload_type = buf[1] & 0x7f;
622
    seq  = (buf[2] << 8) | buf[3];
623
    timestamp = decode_be32(buf + 4);
624
    ssrc = decode_be32(buf + 8);
625
    /* store the ssrc in the RTPDemuxContext */
626
    s->ssrc = ssrc;
627

    
628
    /* NOTE: we can handle only one payload type */
629
    if (s->payload_type != payload_type)
630
        return -1;
631

    
632
    st = s->st;
633
    // only do something with this if all the rtp checks pass...
634
    if(!rtp_valid_packet_in_sequence(&s->statistics, seq))
635
    {
636
        av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
637
               payload_type, seq, ((s->seq + 1) & 0xffff));
638
        return -1;
639
    }
640

    
641
    s->seq = seq;
642
    len -= 12;
643
    buf += 12;
644

    
645
    if (!st) {
646
        /* specific MPEG2TS demux support */
647
        ret = mpegts_parse_packet(s->ts, pkt, buf, len);
648
        if (ret < 0)
649
            return -1;
650
        if (ret < len) {
651
            s->read_buf_size = len - ret;
652
            memcpy(s->buf, buf + ret, s->read_buf_size);
653
            s->read_buf_index = 0;
654
            return 1;
655
        }
656
    } else {
657
        // at this point, the RTP header has been stripped;  This is ASSUMING that there is only 1 CSRC, which in't wise.
658
        switch(st->codec->codec_id) {
659
        case CODEC_ID_MP2:
660
            /* better than nothing: skip mpeg audio RTP header */
661
            if (len <= 4)
662
                return -1;
663
            h = decode_be32(buf);
664
            len -= 4;
665
            buf += 4;
666
            av_new_packet(pkt, len);
667
            memcpy(pkt->data, buf, len);
668
            break;
669
        case CODEC_ID_MPEG1VIDEO:
670
            /* better than nothing: skip mpeg video RTP header */
671
            if (len <= 4)
672
                return -1;
673
            h = decode_be32(buf);
674
            buf += 4;
675
            len -= 4;
676
            if (h & (1 << 26)) {
677
                /* mpeg2 */
678
                if (len <= 4)
679
                    return -1;
680
                buf += 4;
681
                len -= 4;
682
            }
683
            av_new_packet(pkt, len);
684
            memcpy(pkt->data, buf, len);
685
            break;
686
            // moved from below, verbatim.  this is because this section handles packets, and the lower switch handles
687
            // timestamps.
688
            // TODO: Put this into a dynamic packet handler...
689
        case CODEC_ID_AAC:
690
            if (rtp_parse_mp4_au(s, buf))
691
                return -1;
692
            {
693
                rtp_payload_data_t *infos = s->rtp_payload_data;
694
                if (infos == NULL)
695
                    return -1;
696
                buf += infos->au_headers_length_bytes + 2;
697
                len -= infos->au_headers_length_bytes + 2;
698

    
699
                /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
700
                    one au_header */
701
                av_new_packet(pkt, infos->au_headers[0].size);
702
                memcpy(pkt->data, buf, infos->au_headers[0].size);
703
                buf += infos->au_headers[0].size;
704
                len -= infos->au_headers[0].size;
705
            }
706
            s->read_buf_size = len;
707
            s->buf_ptr = buf;
708
            rv= 0;
709
            break;
710
        default:
711
            if(s->parse_packet) {
712
                rv= s->parse_packet(s, pkt, &timestamp, buf, len);
713
            } else {
714
                av_new_packet(pkt, len);
715
                memcpy(pkt->data, buf, len);
716
            }
717
            break;
718
        }
719

    
720
        // now perform timestamp things....
721
        finalize_packet(s, pkt, timestamp);
722
    }
723
    return rv;
724
}
725

    
726
void rtp_parse_close(RTPDemuxContext *s)
727
{
728
    // TODO: fold this into the protocol specific data fields.
729
    if (!strcmp(AVRtpPayloadTypes[s->payload_type].enc_name, "MP2T")) {
730
        mpegts_parse_close(s->ts);
731
    }
732
    av_free(s);
733
}
734

    
735
/* rtp output */
736

    
737
static int rtp_write_header(AVFormatContext *s1)
738
{
739
    RTPDemuxContext *s = s1->priv_data;
740
    int payload_type, max_packet_size, n;
741
    AVStream *st;
742

    
743
    if (s1->nb_streams != 1)
744
        return -1;
745
    st = s1->streams[0];
746

    
747
    payload_type = rtp_get_payload_type(st->codec);
748
    if (payload_type < 0)
749
        payload_type = RTP_PT_PRIVATE; /* private payload type */
750
    s->payload_type = payload_type;
751

    
752
// following 2 FIXMies could be set based on the current time, theres normaly no info leak, as rtp will likely be transmitted immedeatly
753
    s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
754
    s->timestamp = s->base_timestamp;
755
    s->ssrc = 0; /* FIXME: was random(), what should this be? */
756
    s->first_packet = 1;
757

    
758
    max_packet_size = url_fget_max_packet_size(&s1->pb);
759
    if (max_packet_size <= 12)
760
        return AVERROR_IO;
761
    s->max_payload_size = max_packet_size - 12;
762

    
763
    switch(st->codec->codec_id) {
764
    case CODEC_ID_MP2:
765
    case CODEC_ID_MP3:
766
        s->buf_ptr = s->buf + 4;
767
        s->cur_timestamp = 0;
768
        break;
769
    case CODEC_ID_MPEG1VIDEO:
770
        s->cur_timestamp = 0;
771
        break;
772
    case CODEC_ID_MPEG2TS:
773
        n = s->max_payload_size / TS_PACKET_SIZE;
774
        if (n < 1)
775
            n = 1;
776
        s->max_payload_size = n * TS_PACKET_SIZE;
777
        s->buf_ptr = s->buf;
778
        break;
779
    default:
780
        s->buf_ptr = s->buf;
781
        break;
782
    }
783

    
784
    return 0;
785
}
786

    
787
/* send an rtcp sender report packet */
788
static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
789
{
790
    RTPDemuxContext *s = s1->priv_data;
791
#if defined(DEBUG)
792
    printf("RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
793
#endif
794
    put_byte(&s1->pb, (RTP_VERSION << 6));
795
    put_byte(&s1->pb, 200);
796
    put_be16(&s1->pb, 6); /* length in words - 1 */
797
    put_be32(&s1->pb, s->ssrc);
798
    put_be64(&s1->pb, ntp_time);
799
    put_be32(&s1->pb, s->timestamp);
800
    put_be32(&s1->pb, s->packet_count);
801
    put_be32(&s1->pb, s->octet_count);
802
    put_flush_packet(&s1->pb);
803
}
804

    
805
/* send an rtp packet. sequence number is incremented, but the caller
806
   must update the timestamp itself */
807
static void rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
808
{
809
    RTPDemuxContext *s = s1->priv_data;
810

    
811
#ifdef DEBUG
812
    printf("rtp_send_data size=%d\n", len);
813
#endif
814

    
815
    /* build the RTP header */
816
    put_byte(&s1->pb, (RTP_VERSION << 6));
817
    put_byte(&s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
818
    put_be16(&s1->pb, s->seq);
819
    put_be32(&s1->pb, s->timestamp);
820
    put_be32(&s1->pb, s->ssrc);
821

    
822
    put_buffer(&s1->pb, buf1, len);
823
    put_flush_packet(&s1->pb);
824

    
825
    s->seq++;
826
    s->octet_count += len;
827
    s->packet_count++;
828
}
829

    
830
/* send an integer number of samples and compute time stamp and fill
831
   the rtp send buffer before sending. */
832
static void rtp_send_samples(AVFormatContext *s1,
833
                             const uint8_t *buf1, int size, int sample_size)
834
{
835
    RTPDemuxContext *s = s1->priv_data;
836
    int len, max_packet_size, n;
837

    
838
    max_packet_size = (s->max_payload_size / sample_size) * sample_size;
839
    /* not needed, but who nows */
840
    if ((size % sample_size) != 0)
841
        av_abort();
842
    while (size > 0) {
843
        len = (max_packet_size - (s->buf_ptr - s->buf));
844
        if (len > size)
845
            len = size;
846

    
847
        /* copy data */
848
        memcpy(s->buf_ptr, buf1, len);
849
        s->buf_ptr += len;
850
        buf1 += len;
851
        size -= len;
852
        n = (s->buf_ptr - s->buf);
853
        /* if buffer full, then send it */
854
        if (n >= max_packet_size) {
855
            rtp_send_data(s1, s->buf, n, 0);
856
            s->buf_ptr = s->buf;
857
            /* update timestamp */
858
            s->timestamp += n / sample_size;
859
        }
860
    }
861
}
862

    
863
/* NOTE: we suppose that exactly one frame is given as argument here */
864
/* XXX: test it */
865
static void rtp_send_mpegaudio(AVFormatContext *s1,
866
                               const uint8_t *buf1, int size)
867
{
868
    RTPDemuxContext *s = s1->priv_data;
869
    AVStream *st = s1->streams[0];
870
    int len, count, max_packet_size;
871

    
872
    max_packet_size = s->max_payload_size;
873

    
874
    /* test if we must flush because not enough space */
875
    len = (s->buf_ptr - s->buf);
876
    if ((len + size) > max_packet_size) {
877
        if (len > 4) {
878
            rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
879
            s->buf_ptr = s->buf + 4;
880
            /* 90 KHz time stamp */
881
            s->timestamp = s->base_timestamp +
882
                (s->cur_timestamp * 90000LL) / st->codec->sample_rate;
883
        }
884
    }
885

    
886
    /* add the packet */
887
    if (size > max_packet_size) {
888
        /* big packet: fragment */
889
        count = 0;
890
        while (size > 0) {
891
            len = max_packet_size - 4;
892
            if (len > size)
893
                len = size;
894
            /* build fragmented packet */
895
            s->buf[0] = 0;
896
            s->buf[1] = 0;
897
            s->buf[2] = count >> 8;
898
            s->buf[3] = count;
899
            memcpy(s->buf + 4, buf1, len);
900
            rtp_send_data(s1, s->buf, len + 4, 0);
901
            size -= len;
902
            buf1 += len;
903
            count += len;
904
        }
905
    } else {
906
        if (s->buf_ptr == s->buf + 4) {
907
            /* no fragmentation possible */
908
            s->buf[0] = 0;
909
            s->buf[1] = 0;
910
            s->buf[2] = 0;
911
            s->buf[3] = 0;
912
        }
913
        memcpy(s->buf_ptr, buf1, size);
914
        s->buf_ptr += size;
915
    }
916
    s->cur_timestamp += st->codec->frame_size;
917
}
918

    
919
/* NOTE: a single frame must be passed with sequence header if
920
   needed. XXX: use slices. */
921
static void rtp_send_mpegvideo(AVFormatContext *s1,
922
                               const uint8_t *buf1, int size)
923
{
924
    RTPDemuxContext *s = s1->priv_data;
925
    AVStream *st = s1->streams[0];
926
    int len, h, max_packet_size;
927
    uint8_t *q;
928

    
929
    max_packet_size = s->max_payload_size;
930

    
931
    while (size > 0) {
932
        /* XXX: more correct headers */
933
        h = 0;
934
        if (st->codec->sub_id == 2)
935
            h |= 1 << 26; /* mpeg 2 indicator */
936
        q = s->buf;
937
        *q++ = h >> 24;
938
        *q++ = h >> 16;
939
        *q++ = h >> 8;
940
        *q++ = h;
941

    
942
        if (st->codec->sub_id == 2) {
943
            h = 0;
944
            *q++ = h >> 24;
945
            *q++ = h >> 16;
946
            *q++ = h >> 8;
947
            *q++ = h;
948
        }
949

    
950
        len = max_packet_size - (q - s->buf);
951
        if (len > size)
952
            len = size;
953

    
954
        memcpy(q, buf1, len);
955
        q += len;
956

    
957
        /* 90 KHz time stamp */
958
        s->timestamp = s->base_timestamp +
959
            av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
960
        rtp_send_data(s1, s->buf, q - s->buf, (len == size));
961

    
962
        buf1 += len;
963
        size -= len;
964
    }
965
    s->cur_timestamp++;
966
}
967

    
968
static void rtp_send_raw(AVFormatContext *s1,
969
                         const uint8_t *buf1, int size)
970
{
971
    RTPDemuxContext *s = s1->priv_data;
972
    AVStream *st = s1->streams[0];
973
    int len, max_packet_size;
974

    
975
    max_packet_size = s->max_payload_size;
976

    
977
    while (size > 0) {
978
        len = max_packet_size;
979
        if (len > size)
980
            len = size;
981

    
982
        /* 90 KHz time stamp */
983
        s->timestamp = s->base_timestamp +
984
            av_rescale((int64_t)s->cur_timestamp * st->codec->time_base.num, 90000, st->codec->time_base.den); //FIXME pass timestamps
985
        rtp_send_data(s1, buf1, len, (len == size));
986

    
987
        buf1 += len;
988
        size -= len;
989
    }
990
    s->cur_timestamp++;
991
}
992

    
993
/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
994
static void rtp_send_mpegts_raw(AVFormatContext *s1,
995
                                const uint8_t *buf1, int size)
996
{
997
    RTPDemuxContext *s = s1->priv_data;
998
    int len, out_len;
999

    
1000
    while (size >= TS_PACKET_SIZE) {
1001
        len = s->max_payload_size - (s->buf_ptr - s->buf);
1002
        if (len > size)
1003
            len = size;
1004
        memcpy(s->buf_ptr, buf1, len);
1005
        buf1 += len;
1006
        size -= len;
1007
        s->buf_ptr += len;
1008

    
1009
        out_len = s->buf_ptr - s->buf;
1010
        if (out_len >= s->max_payload_size) {
1011
            rtp_send_data(s1, s->buf, out_len, 0);
1012
            s->buf_ptr = s->buf;
1013
        }
1014
    }
1015
}
1016

    
1017
/* write an RTP packet. 'buf1' must contain a single specific frame. */
1018
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
1019
{
1020
    RTPDemuxContext *s = s1->priv_data;
1021
    AVStream *st = s1->streams[0];
1022
    int rtcp_bytes;
1023
    int64_t ntp_time;
1024
    int size= pkt->size;
1025
    uint8_t *buf1= pkt->data;
1026

    
1027
#ifdef DEBUG
1028
    printf("%d: write len=%d\n", pkt->stream_index, size);
1029
#endif
1030

    
1031
    /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
1032
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
1033
        RTCP_TX_RATIO_DEN;
1034
    if (s->first_packet || rtcp_bytes >= 28) {
1035
        /* compute NTP time */
1036
        /* XXX: 90 kHz timestamp hardcoded */
1037
        ntp_time = (pkt->pts << 28) / 5625;
1038
        rtcp_send_sr(s1, ntp_time);
1039
        s->last_octet_count = s->octet_count;
1040
        s->first_packet = 0;
1041
    }
1042

    
1043
    switch(st->codec->codec_id) {
1044
    case CODEC_ID_PCM_MULAW:
1045
    case CODEC_ID_PCM_ALAW:
1046
    case CODEC_ID_PCM_U8:
1047
    case CODEC_ID_PCM_S8:
1048
        rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
1049
        break;
1050
    case CODEC_ID_PCM_U16BE:
1051
    case CODEC_ID_PCM_U16LE:
1052
    case CODEC_ID_PCM_S16BE:
1053
    case CODEC_ID_PCM_S16LE:
1054
        rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
1055
        break;
1056
    case CODEC_ID_MP2:
1057
    case CODEC_ID_MP3:
1058
        rtp_send_mpegaudio(s1, buf1, size);
1059
        break;
1060
    case CODEC_ID_MPEG1VIDEO:
1061
        rtp_send_mpegvideo(s1, buf1, size);
1062
        break;
1063
    case CODEC_ID_MPEG2TS:
1064
        rtp_send_mpegts_raw(s1, buf1, size);
1065
        break;
1066
    default:
1067
        /* better than nothing : send the codec raw data */
1068
        rtp_send_raw(s1, buf1, size);
1069
        break;
1070
    }
1071
    return 0;
1072
}
1073

    
1074
static int rtp_write_trailer(AVFormatContext *s1)
1075
{
1076
    //    RTPDemuxContext *s = s1->priv_data;
1077
    return 0;
1078
}
1079

    
1080
AVOutputFormat rtp_muxer = {
1081
    "rtp",
1082
    "RTP output format",
1083
    NULL,
1084
    NULL,
1085
    sizeof(RTPDemuxContext),
1086
    CODEC_ID_PCM_MULAW,
1087
    CODEC_ID_NONE,
1088
    rtp_write_header,
1089
    rtp_write_packet,
1090
    rtp_write_trailer,
1091
};