Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtpenc.c @ 6399c17d

History | View | Annotate | Download (12.4 KB)

1
/*
2
 * RTP 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

    
22
#include "libavcodec/get_bits.h"
23
#include "avformat.h"
24
#include "mpegts.h"
25

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

    
29
#include "rtpenc.h"
30

    
31
//#define DEBUG
32

    
33
#define RTCP_SR_SIZE 28
34
#define NTP_OFFSET 2208988800ULL
35
#define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL)
36

    
37
static uint64_t ntp_time(void)
38
{
39
  return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
40
}
41

    
42
static int is_supported(enum CodecID id)
43
{
44
    switch(id) {
45
    case CODEC_ID_H263:
46
    case CODEC_ID_H263P:
47
    case CODEC_ID_H264:
48
    case CODEC_ID_MPEG1VIDEO:
49
    case CODEC_ID_MPEG2VIDEO:
50
    case CODEC_ID_MPEG4:
51
    case CODEC_ID_AAC:
52
    case CODEC_ID_MP2:
53
    case CODEC_ID_MP3:
54
    case CODEC_ID_PCM_ALAW:
55
    case CODEC_ID_PCM_MULAW:
56
    case CODEC_ID_PCM_S8:
57
    case CODEC_ID_PCM_S16BE:
58
    case CODEC_ID_PCM_S16LE:
59
    case CODEC_ID_PCM_U16BE:
60
    case CODEC_ID_PCM_U16LE:
61
    case CODEC_ID_PCM_U8:
62
    case CODEC_ID_MPEG2TS:
63
    case CODEC_ID_AMR_NB:
64
    case CODEC_ID_AMR_WB:
65
        return 1;
66
    default:
67
        return 0;
68
    }
69
}
70

    
71
static int rtp_write_header(AVFormatContext *s1)
72
{
73
    RTPMuxContext *s = s1->priv_data;
74
    int payload_type, max_packet_size, n;
75
    AVStream *st;
76

    
77
    if (s1->nb_streams != 1)
78
        return -1;
79
    st = s1->streams[0];
80
    if (!is_supported(st->codec->codec_id)) {
81
        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
82

    
83
        return -1;
84
    }
85

    
86
    payload_type = ff_rtp_get_payload_type(st->codec);
87
    if (payload_type < 0)
88
        payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == CODEC_TYPE_AUDIO);
89
    s->payload_type = payload_type;
90

    
91
// following 2 FIXMEs could be set based on the current time, there is normally no info leak, as RTP will likely be transmitted immediately
92
    s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
93
    s->timestamp = s->base_timestamp;
94
    s->cur_timestamp = 0;
95
    s->ssrc = 0; /* FIXME: was random(), what should this be? */
96
    s->first_packet = 1;
97
    s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
98

    
99
    max_packet_size = url_fget_max_packet_size(s1->pb);
100
    if (max_packet_size <= 12)
101
        return AVERROR(EIO);
102
    s->buf = av_malloc(max_packet_size);
103
    if (s->buf == NULL) {
104
        return AVERROR(ENOMEM);
105
    }
106
    s->max_payload_size = max_packet_size - 12;
107

    
108
    s->max_frames_per_packet = 0;
109
    if (s1->max_delay) {
110
        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
111
            if (st->codec->frame_size == 0) {
112
                av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
113
            } else {
114
                s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN);
115
            }
116
        }
117
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
118
            /* FIXME: We should round down here... */
119
            s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base);
120
        }
121
    }
122

    
123
    av_set_pts_info(st, 32, 1, 90000);
124
    switch(st->codec->codec_id) {
125
    case CODEC_ID_MP2:
126
    case CODEC_ID_MP3:
127
        s->buf_ptr = s->buf + 4;
128
        break;
129
    case CODEC_ID_MPEG1VIDEO:
130
    case CODEC_ID_MPEG2VIDEO:
131
        break;
132
    case CODEC_ID_MPEG2TS:
133
        n = s->max_payload_size / TS_PACKET_SIZE;
134
        if (n < 1)
135
            n = 1;
136
        s->max_payload_size = n * TS_PACKET_SIZE;
137
        s->buf_ptr = s->buf;
138
        break;
139
    case CODEC_ID_AMR_NB:
140
    case CODEC_ID_AMR_WB:
141
        if (!s->max_frames_per_packet)
142
            s->max_frames_per_packet = 12;
143
        if (st->codec->codec_id == CODEC_ID_AMR_NB)
144
            n = 31;
145
        else
146
            n = 61;
147
        /* max_header_toc_size + the largest AMR payload must fit */
148
        if (1 + s->max_frames_per_packet + n > s->max_payload_size) {
149
            av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n");
150
            return -1;
151
        }
152
        if (st->codec->channels != 1) {
153
            av_log(s1, AV_LOG_ERROR, "Only mono is supported\n");
154
            return -1;
155
        }
156
    case CODEC_ID_AAC:
157
        s->num_frames = 0;
158
    default:
159
        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
160
            av_set_pts_info(st, 32, 1, st->codec->sample_rate);
161
        }
162
        s->buf_ptr = s->buf;
163
        break;
164
    }
165

    
166
    return 0;
167
}
168

    
169
/* send an rtcp sender report packet */
170
static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
171
{
172
    RTPMuxContext *s = s1->priv_data;
173
    uint32_t rtp_ts;
174

    
175
    dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
176

    
177
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) s->first_rtcp_ntp_time = ntp_time;
178
    s->last_rtcp_ntp_time = ntp_time;
179
    rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
180
                          s1->streams[0]->time_base) + s->base_timestamp;
181
    put_byte(s1->pb, (RTP_VERSION << 6));
182
    put_byte(s1->pb, 200);
183
    put_be16(s1->pb, 6); /* length in words - 1 */
184
    put_be32(s1->pb, s->ssrc);
185
    put_be32(s1->pb, ntp_time / 1000000);
186
    put_be32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
187
    put_be32(s1->pb, rtp_ts);
188
    put_be32(s1->pb, s->packet_count);
189
    put_be32(s1->pb, s->octet_count);
190
    put_flush_packet(s1->pb);
191
}
192

    
193
/* send an rtp packet. sequence number is incremented, but the caller
194
   must update the timestamp itself */
195
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
196
{
197
    RTPMuxContext *s = s1->priv_data;
198

    
199
    dprintf(s1, "rtp_send_data size=%d\n", len);
200

    
201
    /* build the RTP header */
202
    put_byte(s1->pb, (RTP_VERSION << 6));
203
    put_byte(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
204
    put_be16(s1->pb, s->seq);
205
    put_be32(s1->pb, s->timestamp);
206
    put_be32(s1->pb, s->ssrc);
207

    
208
    put_buffer(s1->pb, buf1, len);
209
    put_flush_packet(s1->pb);
210

    
211
    s->seq++;
212
    s->octet_count += len;
213
    s->packet_count++;
214
}
215

    
216
/* send an integer number of samples and compute time stamp and fill
217
   the rtp send buffer before sending. */
218
static void rtp_send_samples(AVFormatContext *s1,
219
                             const uint8_t *buf1, int size, int sample_size)
220
{
221
    RTPMuxContext *s = s1->priv_data;
222
    int len, max_packet_size, n;
223

    
224
    max_packet_size = (s->max_payload_size / sample_size) * sample_size;
225
    /* not needed, but who nows */
226
    if ((size % sample_size) != 0)
227
        av_abort();
228
    n = 0;
229
    while (size > 0) {
230
        s->buf_ptr = s->buf;
231
        len = FFMIN(max_packet_size, size);
232

    
233
        /* copy data */
234
        memcpy(s->buf_ptr, buf1, len);
235
        s->buf_ptr += len;
236
        buf1 += len;
237
        size -= len;
238
        s->timestamp = s->cur_timestamp + n / sample_size;
239
        ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
240
        n += (s->buf_ptr - s->buf);
241
    }
242
}
243

    
244
/* NOTE: we suppose that exactly one frame is given as argument here */
245
/* XXX: test it */
246
static void rtp_send_mpegaudio(AVFormatContext *s1,
247
                               const uint8_t *buf1, int size)
248
{
249
    RTPMuxContext *s = s1->priv_data;
250
    int len, count, max_packet_size;
251

    
252
    max_packet_size = s->max_payload_size;
253

    
254
    /* test if we must flush because not enough space */
255
    len = (s->buf_ptr - s->buf);
256
    if ((len + size) > max_packet_size) {
257
        if (len > 4) {
258
            ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
259
            s->buf_ptr = s->buf + 4;
260
        }
261
    }
262
    if (s->buf_ptr == s->buf + 4) {
263
        s->timestamp = s->cur_timestamp;
264
    }
265

    
266
    /* add the packet */
267
    if (size > max_packet_size) {
268
        /* big packet: fragment */
269
        count = 0;
270
        while (size > 0) {
271
            len = max_packet_size - 4;
272
            if (len > size)
273
                len = size;
274
            /* build fragmented packet */
275
            s->buf[0] = 0;
276
            s->buf[1] = 0;
277
            s->buf[2] = count >> 8;
278
            s->buf[3] = count;
279
            memcpy(s->buf + 4, buf1, len);
280
            ff_rtp_send_data(s1, s->buf, len + 4, 0);
281
            size -= len;
282
            buf1 += len;
283
            count += len;
284
        }
285
    } else {
286
        if (s->buf_ptr == s->buf + 4) {
287
            /* no fragmentation possible */
288
            s->buf[0] = 0;
289
            s->buf[1] = 0;
290
            s->buf[2] = 0;
291
            s->buf[3] = 0;
292
        }
293
        memcpy(s->buf_ptr, buf1, size);
294
        s->buf_ptr += size;
295
    }
296
}
297

    
298
static void rtp_send_raw(AVFormatContext *s1,
299
                         const uint8_t *buf1, int size)
300
{
301
    RTPMuxContext *s = s1->priv_data;
302
    int len, max_packet_size;
303

    
304
    max_packet_size = s->max_payload_size;
305

    
306
    while (size > 0) {
307
        len = max_packet_size;
308
        if (len > size)
309
            len = size;
310

    
311
        s->timestamp = s->cur_timestamp;
312
        ff_rtp_send_data(s1, buf1, len, (len == size));
313

    
314
        buf1 += len;
315
        size -= len;
316
    }
317
}
318

    
319
/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
320
static void rtp_send_mpegts_raw(AVFormatContext *s1,
321
                                const uint8_t *buf1, int size)
322
{
323
    RTPMuxContext *s = s1->priv_data;
324
    int len, out_len;
325

    
326
    while (size >= TS_PACKET_SIZE) {
327
        len = s->max_payload_size - (s->buf_ptr - s->buf);
328
        if (len > size)
329
            len = size;
330
        memcpy(s->buf_ptr, buf1, len);
331
        buf1 += len;
332
        size -= len;
333
        s->buf_ptr += len;
334

    
335
        out_len = s->buf_ptr - s->buf;
336
        if (out_len >= s->max_payload_size) {
337
            ff_rtp_send_data(s1, s->buf, out_len, 0);
338
            s->buf_ptr = s->buf;
339
        }
340
    }
341
}
342

    
343
/* write an RTP packet. 'buf1' must contain a single specific frame. */
344
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
345
{
346
    RTPMuxContext *s = s1->priv_data;
347
    AVStream *st = s1->streams[0];
348
    int rtcp_bytes;
349
    int size= pkt->size;
350
    uint8_t *buf1= pkt->data;
351

    
352
    dprintf(s1, "%d: write len=%d\n", pkt->stream_index, size);
353

    
354
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
355
        RTCP_TX_RATIO_DEN;
356
    if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
357
                           (ntp_time() - s->last_rtcp_ntp_time > 5000000))) {
358
        rtcp_send_sr(s1, ntp_time());
359
        s->last_octet_count = s->octet_count;
360
        s->first_packet = 0;
361
    }
362
    s->cur_timestamp = s->base_timestamp + pkt->pts;
363

    
364
    switch(st->codec->codec_id) {
365
    case CODEC_ID_PCM_MULAW:
366
    case CODEC_ID_PCM_ALAW:
367
    case CODEC_ID_PCM_U8:
368
    case CODEC_ID_PCM_S8:
369
        rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
370
        break;
371
    case CODEC_ID_PCM_U16BE:
372
    case CODEC_ID_PCM_U16LE:
373
    case CODEC_ID_PCM_S16BE:
374
    case CODEC_ID_PCM_S16LE:
375
        rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
376
        break;
377
    case CODEC_ID_MP2:
378
    case CODEC_ID_MP3:
379
        rtp_send_mpegaudio(s1, buf1, size);
380
        break;
381
    case CODEC_ID_MPEG1VIDEO:
382
    case CODEC_ID_MPEG2VIDEO:
383
        ff_rtp_send_mpegvideo(s1, buf1, size);
384
        break;
385
    case CODEC_ID_AAC:
386
        ff_rtp_send_aac(s1, buf1, size);
387
        break;
388
    case CODEC_ID_AMR_NB:
389
    case CODEC_ID_AMR_WB:
390
        ff_rtp_send_amr(s1, buf1, size);
391
        break;
392
    case CODEC_ID_MPEG2TS:
393
        rtp_send_mpegts_raw(s1, buf1, size);
394
        break;
395
    case CODEC_ID_H264:
396
        ff_rtp_send_h264(s1, buf1, size);
397
        break;
398
    case CODEC_ID_H263:
399
    case CODEC_ID_H263P:
400
        ff_rtp_send_h263(s1, buf1, size);
401
        break;
402
    default:
403
        /* better than nothing : send the codec raw data */
404
        rtp_send_raw(s1, buf1, size);
405
        break;
406
    }
407
    return 0;
408
}
409

    
410
static int rtp_write_trailer(AVFormatContext *s1)
411
{
412
    RTPMuxContext *s = s1->priv_data;
413

    
414
    av_freep(&s->buf);
415

    
416
    return 0;
417
}
418

    
419
AVOutputFormat rtp_muxer = {
420
    "rtp",
421
    NULL_IF_CONFIG_SMALL("RTP output format"),
422
    NULL,
423
    NULL,
424
    sizeof(RTPMuxContext),
425
    CODEC_ID_PCM_MULAW,
426
    CODEC_ID_NONE,
427
    rtp_write_header,
428
    rtp_write_packet,
429
    rtp_write_trailer,
430
};