~ubuntu-branches/ubuntu/utopic/libav/utopic

« back to all changes in this revision

Viewing changes to libavformat/rtpenc.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-03-20 12:09:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110320120931-nfhi9tiok27gxhw1
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "avformat.h"
 
23
#include "mpegts.h"
 
24
#include "internal.h"
 
25
#include "libavutil/random_seed.h"
 
26
 
 
27
#include <unistd.h>
 
28
 
 
29
#include "rtpenc.h"
 
30
 
 
31
//#define DEBUG
 
32
 
 
33
#define RTCP_SR_SIZE 28
 
34
 
 
35
static int is_supported(enum CodecID id)
 
36
{
 
37
    switch(id) {
 
38
    case CODEC_ID_H263:
 
39
    case CODEC_ID_H263P:
 
40
    case CODEC_ID_H264:
 
41
    case CODEC_ID_MPEG1VIDEO:
 
42
    case CODEC_ID_MPEG2VIDEO:
 
43
    case CODEC_ID_MPEG4:
 
44
    case CODEC_ID_AAC:
 
45
    case CODEC_ID_MP2:
 
46
    case CODEC_ID_MP3:
 
47
    case CODEC_ID_PCM_ALAW:
 
48
    case CODEC_ID_PCM_MULAW:
 
49
    case CODEC_ID_PCM_S8:
 
50
    case CODEC_ID_PCM_S16BE:
 
51
    case CODEC_ID_PCM_S16LE:
 
52
    case CODEC_ID_PCM_U16BE:
 
53
    case CODEC_ID_PCM_U16LE:
 
54
    case CODEC_ID_PCM_U8:
 
55
    case CODEC_ID_MPEG2TS:
 
56
    case CODEC_ID_AMR_NB:
 
57
    case CODEC_ID_AMR_WB:
 
58
        return 1;
 
59
    default:
 
60
        return 0;
 
61
    }
 
62
}
 
63
 
 
64
static int rtp_write_header(AVFormatContext *s1)
 
65
{
 
66
    RTPMuxContext *s = s1->priv_data;
 
67
    int max_packet_size, n;
 
68
    AVStream *st;
 
69
 
 
70
    if (s1->nb_streams != 1)
 
71
        return -1;
 
72
    st = s1->streams[0];
 
73
    if (!is_supported(st->codec->codec_id)) {
 
74
        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
 
75
 
 
76
        return -1;
 
77
    }
 
78
 
 
79
    s->payload_type = ff_rtp_get_payload_type(st->codec);
 
80
    if (s->payload_type < 0)
 
81
        s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == AVMEDIA_TYPE_AUDIO);
 
82
 
 
83
    s->base_timestamp = ff_random_get_seed();
 
84
    s->timestamp = s->base_timestamp;
 
85
    s->cur_timestamp = 0;
 
86
    s->ssrc = ff_random_get_seed();
 
87
    s->first_packet = 1;
 
88
    s->first_rtcp_ntp_time = ff_ntp_time();
 
89
    if (s1->start_time_realtime)
 
90
        /* Round the NTP time to whole milliseconds. */
 
91
        s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 +
 
92
                                 NTP_OFFSET_US;
 
93
 
 
94
    max_packet_size = url_fget_max_packet_size(s1->pb);
 
95
    if (max_packet_size <= 12)
 
96
        return AVERROR(EIO);
 
97
    s->buf = av_malloc(max_packet_size);
 
98
    if (s->buf == NULL) {
 
99
        return AVERROR(ENOMEM);
 
100
    }
 
101
    s->max_payload_size = max_packet_size - 12;
 
102
 
 
103
    s->max_frames_per_packet = 0;
 
104
    if (s1->max_delay) {
 
105
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 
106
            if (st->codec->frame_size == 0) {
 
107
                av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
 
108
            } else {
 
109
                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);
 
110
            }
 
111
        }
 
112
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 
113
            /* FIXME: We should round down here... */
 
114
            s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base);
 
115
        }
 
116
    }
 
117
 
 
118
    av_set_pts_info(st, 32, 1, 90000);
 
119
    switch(st->codec->codec_id) {
 
120
    case CODEC_ID_MP2:
 
121
    case CODEC_ID_MP3:
 
122
        s->buf_ptr = s->buf + 4;
 
123
        break;
 
124
    case CODEC_ID_MPEG1VIDEO:
 
125
    case CODEC_ID_MPEG2VIDEO:
 
126
        break;
 
127
    case CODEC_ID_MPEG2TS:
 
128
        n = s->max_payload_size / TS_PACKET_SIZE;
 
129
        if (n < 1)
 
130
            n = 1;
 
131
        s->max_payload_size = n * TS_PACKET_SIZE;
 
132
        s->buf_ptr = s->buf;
 
133
        break;
 
134
    case CODEC_ID_AMR_NB:
 
135
    case CODEC_ID_AMR_WB:
 
136
        if (!s->max_frames_per_packet)
 
137
            s->max_frames_per_packet = 12;
 
138
        if (st->codec->codec_id == CODEC_ID_AMR_NB)
 
139
            n = 31;
 
140
        else
 
141
            n = 61;
 
142
        /* max_header_toc_size + the largest AMR payload must fit */
 
143
        if (1 + s->max_frames_per_packet + n > s->max_payload_size) {
 
144
            av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n");
 
145
            return -1;
 
146
        }
 
147
        if (st->codec->channels != 1) {
 
148
            av_log(s1, AV_LOG_ERROR, "Only mono is supported\n");
 
149
            return -1;
 
150
        }
 
151
    case CODEC_ID_AAC:
 
152
        s->num_frames = 0;
 
153
    default:
 
154
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 
155
            av_set_pts_info(st, 32, 1, st->codec->sample_rate);
 
156
        }
 
157
        s->buf_ptr = s->buf;
 
158
        break;
 
159
    }
 
160
 
 
161
    return 0;
 
162
}
 
163
 
 
164
/* send an rtcp sender report packet */
 
165
static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
 
166
{
 
167
    RTPMuxContext *s = s1->priv_data;
 
168
    uint32_t rtp_ts;
 
169
 
 
170
    dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
 
171
 
 
172
    s->last_rtcp_ntp_time = ntp_time;
 
173
    rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
 
174
                          s1->streams[0]->time_base) + s->base_timestamp;
 
175
    put_byte(s1->pb, (RTP_VERSION << 6));
 
176
    put_byte(s1->pb, 200);
 
177
    put_be16(s1->pb, 6); /* length in words - 1 */
 
178
    put_be32(s1->pb, s->ssrc);
 
179
    put_be32(s1->pb, ntp_time / 1000000);
 
180
    put_be32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
 
181
    put_be32(s1->pb, rtp_ts);
 
182
    put_be32(s1->pb, s->packet_count);
 
183
    put_be32(s1->pb, s->octet_count);
 
184
    put_flush_packet(s1->pb);
 
185
}
 
186
 
 
187
/* send an rtp packet. sequence number is incremented, but the caller
 
188
   must update the timestamp itself */
 
189
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
 
190
{
 
191
    RTPMuxContext *s = s1->priv_data;
 
192
 
 
193
    dprintf(s1, "rtp_send_data size=%d\n", len);
 
194
 
 
195
    /* build the RTP header */
 
196
    put_byte(s1->pb, (RTP_VERSION << 6));
 
197
    put_byte(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
 
198
    put_be16(s1->pb, s->seq);
 
199
    put_be32(s1->pb, s->timestamp);
 
200
    put_be32(s1->pb, s->ssrc);
 
201
 
 
202
    put_buffer(s1->pb, buf1, len);
 
203
    put_flush_packet(s1->pb);
 
204
 
 
205
    s->seq++;
 
206
    s->octet_count += len;
 
207
    s->packet_count++;
 
208
}
 
209
 
 
210
/* send an integer number of samples and compute time stamp and fill
 
211
   the rtp send buffer before sending. */
 
212
static void rtp_send_samples(AVFormatContext *s1,
 
213
                             const uint8_t *buf1, int size, int sample_size)
 
214
{
 
215
    RTPMuxContext *s = s1->priv_data;
 
216
    int len, max_packet_size, n;
 
217
 
 
218
    max_packet_size = (s->max_payload_size / sample_size) * sample_size;
 
219
    /* not needed, but who nows */
 
220
    if ((size % sample_size) != 0)
 
221
        av_abort();
 
222
    n = 0;
 
223
    while (size > 0) {
 
224
        s->buf_ptr = s->buf;
 
225
        len = FFMIN(max_packet_size, size);
 
226
 
 
227
        /* copy data */
 
228
        memcpy(s->buf_ptr, buf1, len);
 
229
        s->buf_ptr += len;
 
230
        buf1 += len;
 
231
        size -= len;
 
232
        s->timestamp = s->cur_timestamp + n / sample_size;
 
233
        ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
 
234
        n += (s->buf_ptr - s->buf);
 
235
    }
 
236
}
 
237
 
 
238
static void rtp_send_mpegaudio(AVFormatContext *s1,
 
239
                               const uint8_t *buf1, int size)
 
240
{
 
241
    RTPMuxContext *s = s1->priv_data;
 
242
    int len, count, max_packet_size;
 
243
 
 
244
    max_packet_size = s->max_payload_size;
 
245
 
 
246
    /* test if we must flush because not enough space */
 
247
    len = (s->buf_ptr - s->buf);
 
248
    if ((len + size) > max_packet_size) {
 
249
        if (len > 4) {
 
250
            ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
 
251
            s->buf_ptr = s->buf + 4;
 
252
        }
 
253
    }
 
254
    if (s->buf_ptr == s->buf + 4) {
 
255
        s->timestamp = s->cur_timestamp;
 
256
    }
 
257
 
 
258
    /* add the packet */
 
259
    if (size > max_packet_size) {
 
260
        /* big packet: fragment */
 
261
        count = 0;
 
262
        while (size > 0) {
 
263
            len = max_packet_size - 4;
 
264
            if (len > size)
 
265
                len = size;
 
266
            /* build fragmented packet */
 
267
            s->buf[0] = 0;
 
268
            s->buf[1] = 0;
 
269
            s->buf[2] = count >> 8;
 
270
            s->buf[3] = count;
 
271
            memcpy(s->buf + 4, buf1, len);
 
272
            ff_rtp_send_data(s1, s->buf, len + 4, 0);
 
273
            size -= len;
 
274
            buf1 += len;
 
275
            count += len;
 
276
        }
 
277
    } else {
 
278
        if (s->buf_ptr == s->buf + 4) {
 
279
            /* no fragmentation possible */
 
280
            s->buf[0] = 0;
 
281
            s->buf[1] = 0;
 
282
            s->buf[2] = 0;
 
283
            s->buf[3] = 0;
 
284
        }
 
285
        memcpy(s->buf_ptr, buf1, size);
 
286
        s->buf_ptr += size;
 
287
    }
 
288
}
 
289
 
 
290
static void rtp_send_raw(AVFormatContext *s1,
 
291
                         const uint8_t *buf1, int size)
 
292
{
 
293
    RTPMuxContext *s = s1->priv_data;
 
294
    int len, max_packet_size;
 
295
 
 
296
    max_packet_size = s->max_payload_size;
 
297
 
 
298
    while (size > 0) {
 
299
        len = max_packet_size;
 
300
        if (len > size)
 
301
            len = size;
 
302
 
 
303
        s->timestamp = s->cur_timestamp;
 
304
        ff_rtp_send_data(s1, buf1, len, (len == size));
 
305
 
 
306
        buf1 += len;
 
307
        size -= len;
 
308
    }
 
309
}
 
310
 
 
311
/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
 
312
static void rtp_send_mpegts_raw(AVFormatContext *s1,
 
313
                                const uint8_t *buf1, int size)
 
314
{
 
315
    RTPMuxContext *s = s1->priv_data;
 
316
    int len, out_len;
 
317
 
 
318
    while (size >= TS_PACKET_SIZE) {
 
319
        len = s->max_payload_size - (s->buf_ptr - s->buf);
 
320
        if (len > size)
 
321
            len = size;
 
322
        memcpy(s->buf_ptr, buf1, len);
 
323
        buf1 += len;
 
324
        size -= len;
 
325
        s->buf_ptr += len;
 
326
 
 
327
        out_len = s->buf_ptr - s->buf;
 
328
        if (out_len >= s->max_payload_size) {
 
329
            ff_rtp_send_data(s1, s->buf, out_len, 0);
 
330
            s->buf_ptr = s->buf;
 
331
        }
 
332
    }
 
333
}
 
334
 
 
335
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
 
336
{
 
337
    RTPMuxContext *s = s1->priv_data;
 
338
    AVStream *st = s1->streams[0];
 
339
    int rtcp_bytes;
 
340
    int size= pkt->size;
 
341
 
 
342
    dprintf(s1, "%d: write len=%d\n", pkt->stream_index, size);
 
343
 
 
344
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
 
345
        RTCP_TX_RATIO_DEN;
 
346
    if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
 
347
                           (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) {
 
348
        rtcp_send_sr(s1, ff_ntp_time());
 
349
        s->last_octet_count = s->octet_count;
 
350
        s->first_packet = 0;
 
351
    }
 
352
    s->cur_timestamp = s->base_timestamp + pkt->pts;
 
353
 
 
354
    switch(st->codec->codec_id) {
 
355
    case CODEC_ID_PCM_MULAW:
 
356
    case CODEC_ID_PCM_ALAW:
 
357
    case CODEC_ID_PCM_U8:
 
358
    case CODEC_ID_PCM_S8:
 
359
        rtp_send_samples(s1, pkt->data, size, 1 * st->codec->channels);
 
360
        break;
 
361
    case CODEC_ID_PCM_U16BE:
 
362
    case CODEC_ID_PCM_U16LE:
 
363
    case CODEC_ID_PCM_S16BE:
 
364
    case CODEC_ID_PCM_S16LE:
 
365
        rtp_send_samples(s1, pkt->data, size, 2 * st->codec->channels);
 
366
        break;
 
367
    case CODEC_ID_MP2:
 
368
    case CODEC_ID_MP3:
 
369
        rtp_send_mpegaudio(s1, pkt->data, size);
 
370
        break;
 
371
    case CODEC_ID_MPEG1VIDEO:
 
372
    case CODEC_ID_MPEG2VIDEO:
 
373
        ff_rtp_send_mpegvideo(s1, pkt->data, size);
 
374
        break;
 
375
    case CODEC_ID_AAC:
 
376
        ff_rtp_send_aac(s1, pkt->data, size);
 
377
        break;
 
378
    case CODEC_ID_AMR_NB:
 
379
    case CODEC_ID_AMR_WB:
 
380
        ff_rtp_send_amr(s1, pkt->data, size);
 
381
        break;
 
382
    case CODEC_ID_MPEG2TS:
 
383
        rtp_send_mpegts_raw(s1, pkt->data, size);
 
384
        break;
 
385
    case CODEC_ID_H264:
 
386
        ff_rtp_send_h264(s1, pkt->data, size);
 
387
        break;
 
388
    case CODEC_ID_H263:
 
389
    case CODEC_ID_H263P:
 
390
        ff_rtp_send_h263(s1, pkt->data, size);
 
391
        break;
 
392
    default:
 
393
        /* better than nothing : send the codec raw data */
 
394
        rtp_send_raw(s1, pkt->data, size);
 
395
        break;
 
396
    }
 
397
    return 0;
 
398
}
 
399
 
 
400
static int rtp_write_trailer(AVFormatContext *s1)
 
401
{
 
402
    RTPMuxContext *s = s1->priv_data;
 
403
 
 
404
    av_freep(&s->buf);
 
405
 
 
406
    return 0;
 
407
}
 
408
 
 
409
AVOutputFormat rtp_muxer = {
 
410
    "rtp",
 
411
    NULL_IF_CONFIG_SMALL("RTP output format"),
 
412
    NULL,
 
413
    NULL,
 
414
    sizeof(RTPMuxContext),
 
415
    CODEC_ID_PCM_MULAW,
 
416
    CODEC_ID_NONE,
 
417
    rtp_write_header,
 
418
    rtp_write_packet,
 
419
    rtp_write_trailer,
 
420
};