Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6148 | serge | 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/mathematics.h" |
||
26 | #include "libavutil/random_seed.h" |
||
27 | #include "libavutil/opt.h" |
||
28 | |||
29 | #include "rtpenc.h" |
||
30 | |||
31 | static const AVOption options[] = { |
||
32 | FF_RTP_FLAG_OPTS(RTPMuxContext, flags), |
||
33 | { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM }, |
||
34 | { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, |
||
35 | { "cname", "CNAME to include in RTCP SR packets", offsetof(RTPMuxContext, cname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, |
||
36 | { "seq", "Starting sequence number", offsetof(RTPMuxContext, seq), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, AV_OPT_FLAG_ENCODING_PARAM }, |
||
37 | { NULL }, |
||
38 | }; |
||
39 | |||
40 | static const AVClass rtp_muxer_class = { |
||
41 | .class_name = "RTP muxer", |
||
42 | .item_name = av_default_item_name, |
||
43 | .option = options, |
||
44 | .version = LIBAVUTIL_VERSION_INT, |
||
45 | }; |
||
46 | |||
47 | #define RTCP_SR_SIZE 28 |
||
48 | |||
49 | static int is_supported(enum AVCodecID id) |
||
50 | { |
||
51 | switch(id) { |
||
52 | case AV_CODEC_ID_H263: |
||
53 | case AV_CODEC_ID_H263P: |
||
54 | case AV_CODEC_ID_H264: |
||
55 | case AV_CODEC_ID_MPEG1VIDEO: |
||
56 | case AV_CODEC_ID_MPEG2VIDEO: |
||
57 | case AV_CODEC_ID_MPEG4: |
||
58 | case AV_CODEC_ID_AAC: |
||
59 | case AV_CODEC_ID_MP2: |
||
60 | case AV_CODEC_ID_MP3: |
||
61 | case AV_CODEC_ID_PCM_ALAW: |
||
62 | case AV_CODEC_ID_PCM_MULAW: |
||
63 | case AV_CODEC_ID_PCM_S8: |
||
64 | case AV_CODEC_ID_PCM_S16BE: |
||
65 | case AV_CODEC_ID_PCM_S16LE: |
||
66 | case AV_CODEC_ID_PCM_U16BE: |
||
67 | case AV_CODEC_ID_PCM_U16LE: |
||
68 | case AV_CODEC_ID_PCM_U8: |
||
69 | case AV_CODEC_ID_MPEG2TS: |
||
70 | case AV_CODEC_ID_AMR_NB: |
||
71 | case AV_CODEC_ID_AMR_WB: |
||
72 | case AV_CODEC_ID_VORBIS: |
||
73 | case AV_CODEC_ID_THEORA: |
||
74 | case AV_CODEC_ID_VP8: |
||
75 | case AV_CODEC_ID_ADPCM_G722: |
||
76 | case AV_CODEC_ID_ADPCM_G726: |
||
77 | case AV_CODEC_ID_ILBC: |
||
78 | case AV_CODEC_ID_MJPEG: |
||
79 | case AV_CODEC_ID_SPEEX: |
||
80 | case AV_CODEC_ID_OPUS: |
||
81 | return 1; |
||
82 | default: |
||
83 | return 0; |
||
84 | } |
||
85 | } |
||
86 | |||
87 | static int rtp_write_header(AVFormatContext *s1) |
||
88 | { |
||
89 | RTPMuxContext *s = s1->priv_data; |
||
90 | int n; |
||
91 | AVStream *st; |
||
92 | |||
93 | if (s1->nb_streams != 1) { |
||
94 | av_log(s1, AV_LOG_ERROR, "Only one stream supported in the RTP muxer\n"); |
||
95 | return AVERROR(EINVAL); |
||
96 | } |
||
97 | st = s1->streams[0]; |
||
98 | if (!is_supported(st->codec->codec_id)) { |
||
99 | av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id)); |
||
100 | |||
101 | return -1; |
||
102 | } |
||
103 | |||
104 | if (s->payload_type < 0) { |
||
105 | /* Re-validate non-dynamic payload types */ |
||
106 | if (st->id < RTP_PT_PRIVATE) |
||
107 | st->id = ff_rtp_get_payload_type(s1, st->codec, -1); |
||
108 | |||
109 | s->payload_type = st->id; |
||
110 | } else { |
||
111 | /* private option takes priority */ |
||
112 | st->id = s->payload_type; |
||
113 | } |
||
114 | |||
115 | s->base_timestamp = av_get_random_seed(); |
||
116 | s->timestamp = s->base_timestamp; |
||
117 | s->cur_timestamp = 0; |
||
118 | if (!s->ssrc) |
||
119 | s->ssrc = av_get_random_seed(); |
||
120 | s->first_packet = 1; |
||
121 | s->first_rtcp_ntp_time = ff_ntp_time(); |
||
122 | if (s1->start_time_realtime) |
||
123 | /* Round the NTP time to whole milliseconds. */ |
||
124 | s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 + |
||
125 | NTP_OFFSET_US; |
||
126 | // Pick a random sequence start number, but in the lower end of the |
||
127 | // available range, so that any wraparound doesn't happen immediately. |
||
128 | // (Immediate wraparound would be an issue for SRTP.) |
||
129 | if (s->seq < 0) { |
||
130 | if (st->codec->flags & CODEC_FLAG_BITEXACT) { |
||
131 | s->seq = 0; |
||
132 | } else |
||
133 | s->seq = av_get_random_seed() & 0x0fff; |
||
134 | } else |
||
135 | s->seq &= 0xffff; // Use the given parameter, wrapped to the right interval |
||
136 | |||
137 | if (s1->packet_size) { |
||
138 | if (s1->pb->max_packet_size) |
||
139 | s1->packet_size = FFMIN(s1->packet_size, |
||
140 | s1->pb->max_packet_size); |
||
141 | } else |
||
142 | s1->packet_size = s1->pb->max_packet_size; |
||
143 | if (s1->packet_size <= 12) { |
||
144 | av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", s1->packet_size); |
||
145 | return AVERROR(EIO); |
||
146 | } |
||
147 | s->buf = av_malloc(s1->packet_size); |
||
148 | if (s->buf == NULL) { |
||
149 | return AVERROR(ENOMEM); |
||
150 | } |
||
151 | s->max_payload_size = s1->packet_size - 12; |
||
152 | |||
153 | s->max_frames_per_packet = 0; |
||
154 | if (s1->max_delay > 0) { |
||
155 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { |
||
156 | int frame_size = av_get_audio_frame_duration(st->codec, 0); |
||
157 | if (!frame_size) |
||
158 | frame_size = st->codec->frame_size; |
||
159 | if (frame_size == 0) { |
||
160 | av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n"); |
||
161 | } else { |
||
162 | s->max_frames_per_packet = |
||
163 | av_rescale_q_rnd(s1->max_delay, |
||
164 | AV_TIME_BASE_Q, |
||
165 | (AVRational){ frame_size, st->codec->sample_rate }, |
||
166 | AV_ROUND_DOWN); |
||
167 | } |
||
168 | } |
||
169 | if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
||
170 | /* FIXME: We should round down here... */ |
||
171 | s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base); |
||
172 | } |
||
173 | } |
||
174 | |||
175 | avpriv_set_pts_info(st, 32, 1, 90000); |
||
176 | switch(st->codec->codec_id) { |
||
177 | case AV_CODEC_ID_MP2: |
||
178 | case AV_CODEC_ID_MP3: |
||
179 | s->buf_ptr = s->buf + 4; |
||
180 | break; |
||
181 | case AV_CODEC_ID_MPEG1VIDEO: |
||
182 | case AV_CODEC_ID_MPEG2VIDEO: |
||
183 | break; |
||
184 | case AV_CODEC_ID_MPEG2TS: |
||
185 | n = s->max_payload_size / TS_PACKET_SIZE; |
||
186 | if (n < 1) |
||
187 | n = 1; |
||
188 | s->max_payload_size = n * TS_PACKET_SIZE; |
||
189 | s->buf_ptr = s->buf; |
||
190 | break; |
||
191 | case AV_CODEC_ID_H264: |
||
192 | /* check for H.264 MP4 syntax */ |
||
193 | if (st->codec->extradata_size > 4 && st->codec->extradata[0] == 1) { |
||
194 | s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1; |
||
195 | } |
||
196 | break; |
||
197 | case AV_CODEC_ID_VORBIS: |
||
198 | case AV_CODEC_ID_THEORA: |
||
199 | if (!s->max_frames_per_packet) s->max_frames_per_packet = 15; |
||
200 | s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15); |
||
201 | s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length |
||
202 | s->num_frames = 0; |
||
203 | goto defaultcase; |
||
204 | case AV_CODEC_ID_ADPCM_G722: |
||
205 | /* Due to a historical error, the clock rate for G722 in RTP is |
||
206 | * 8000, even if the sample rate is 16000. See RFC 3551. */ |
||
207 | avpriv_set_pts_info(st, 32, 1, 8000); |
||
208 | break; |
||
209 | case AV_CODEC_ID_OPUS: |
||
210 | if (st->codec->channels > 2) { |
||
211 | av_log(s1, AV_LOG_ERROR, "Multistream opus not supported in RTP\n"); |
||
212 | goto fail; |
||
213 | } |
||
214 | /* The opus RTP RFC says that all opus streams should use 48000 Hz |
||
215 | * as clock rate, since all opus sample rates can be expressed in |
||
216 | * this clock rate, and sample rate changes on the fly are supported. */ |
||
217 | avpriv_set_pts_info(st, 32, 1, 48000); |
||
218 | break; |
||
219 | case AV_CODEC_ID_ILBC: |
||
220 | if (st->codec->block_align != 38 && st->codec->block_align != 50) { |
||
221 | av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n"); |
||
222 | goto fail; |
||
223 | } |
||
224 | if (!s->max_frames_per_packet) |
||
225 | s->max_frames_per_packet = 1; |
||
226 | s->max_frames_per_packet = FFMIN(s->max_frames_per_packet, |
||
227 | s->max_payload_size / st->codec->block_align); |
||
228 | goto defaultcase; |
||
229 | case AV_CODEC_ID_AMR_NB: |
||
230 | case AV_CODEC_ID_AMR_WB: |
||
231 | if (!s->max_frames_per_packet) |
||
232 | s->max_frames_per_packet = 12; |
||
233 | if (st->codec->codec_id == AV_CODEC_ID_AMR_NB) |
||
234 | n = 31; |
||
235 | else |
||
236 | n = 61; |
||
237 | /* max_header_toc_size + the largest AMR payload must fit */ |
||
238 | if (1 + s->max_frames_per_packet + n > s->max_payload_size) { |
||
239 | av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n"); |
||
240 | goto fail; |
||
241 | } |
||
242 | if (st->codec->channels != 1) { |
||
243 | av_log(s1, AV_LOG_ERROR, "Only mono is supported\n"); |
||
244 | goto fail; |
||
245 | } |
||
246 | case AV_CODEC_ID_AAC: |
||
247 | s->num_frames = 0; |
||
248 | default: |
||
249 | defaultcase: |
||
250 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { |
||
251 | avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); |
||
252 | } |
||
253 | s->buf_ptr = s->buf; |
||
254 | break; |
||
255 | } |
||
256 | |||
257 | return 0; |
||
258 | |||
259 | fail: |
||
260 | av_freep(&s->buf); |
||
261 | return AVERROR(EINVAL); |
||
262 | } |
||
263 | |||
264 | /* send an rtcp sender report packet */ |
||
265 | static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) |
||
266 | { |
||
267 | RTPMuxContext *s = s1->priv_data; |
||
268 | uint32_t rtp_ts; |
||
269 | |||
270 | av_dlog(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); |
||
271 | |||
272 | s->last_rtcp_ntp_time = ntp_time; |
||
273 | rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, |
||
274 | s1->streams[0]->time_base) + s->base_timestamp; |
||
275 | avio_w8(s1->pb, (RTP_VERSION << 6)); |
||
276 | avio_w8(s1->pb, RTCP_SR); |
||
277 | avio_wb16(s1->pb, 6); /* length in words - 1 */ |
||
278 | avio_wb32(s1->pb, s->ssrc); |
||
279 | avio_wb64(s1->pb, NTP_TO_RTP_FORMAT(ntp_time)); |
||
280 | avio_wb32(s1->pb, rtp_ts); |
||
281 | avio_wb32(s1->pb, s->packet_count); |
||
282 | avio_wb32(s1->pb, s->octet_count); |
||
283 | |||
284 | if (s->cname) { |
||
285 | int len = FFMIN(strlen(s->cname), 255); |
||
286 | avio_w8(s1->pb, (RTP_VERSION << 6) + 1); |
||
287 | avio_w8(s1->pb, RTCP_SDES); |
||
288 | avio_wb16(s1->pb, (7 + len + 3) / 4); /* length in words - 1 */ |
||
289 | |||
290 | avio_wb32(s1->pb, s->ssrc); |
||
291 | avio_w8(s1->pb, 0x01); /* CNAME */ |
||
292 | avio_w8(s1->pb, len); |
||
293 | avio_write(s1->pb, s->cname, len); |
||
294 | avio_w8(s1->pb, 0); /* END */ |
||
295 | for (len = (7 + len) % 4; len % 4; len++) |
||
296 | avio_w8(s1->pb, 0); |
||
297 | } |
||
298 | |||
299 | avio_flush(s1->pb); |
||
300 | } |
||
301 | |||
302 | /* send an rtp packet. sequence number is incremented, but the caller |
||
303 | must update the timestamp itself */ |
||
304 | void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) |
||
305 | { |
||
306 | RTPMuxContext *s = s1->priv_data; |
||
307 | |||
308 | av_dlog(s1, "rtp_send_data size=%d\n", len); |
||
309 | |||
310 | /* build the RTP header */ |
||
311 | avio_w8(s1->pb, (RTP_VERSION << 6)); |
||
312 | avio_w8(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7)); |
||
313 | avio_wb16(s1->pb, s->seq); |
||
314 | avio_wb32(s1->pb, s->timestamp); |
||
315 | avio_wb32(s1->pb, s->ssrc); |
||
316 | |||
317 | avio_write(s1->pb, buf1, len); |
||
318 | avio_flush(s1->pb); |
||
319 | |||
320 | s->seq = (s->seq + 1) & 0xffff; |
||
321 | s->octet_count += len; |
||
322 | s->packet_count++; |
||
323 | } |
||
324 | |||
325 | /* send an integer number of samples and compute time stamp and fill |
||
326 | the rtp send buffer before sending. */ |
||
327 | static int rtp_send_samples(AVFormatContext *s1, |
||
328 | const uint8_t *buf1, int size, int sample_size_bits) |
||
329 | { |
||
330 | RTPMuxContext *s = s1->priv_data; |
||
331 | int len, max_packet_size, n; |
||
332 | /* Calculate the number of bytes to get samples aligned on a byte border */ |
||
333 | int aligned_samples_size = sample_size_bits/av_gcd(sample_size_bits, 8); |
||
334 | |||
335 | max_packet_size = (s->max_payload_size / aligned_samples_size) * aligned_samples_size; |
||
336 | /* Not needed, but who knows. Don't check if samples aren't an even number of bytes. */ |
||
337 | if ((sample_size_bits % 8) == 0 && ((8 * size) % sample_size_bits) != 0) |
||
338 | return AVERROR(EINVAL); |
||
339 | n = 0; |
||
340 | while (size > 0) { |
||
341 | s->buf_ptr = s->buf; |
||
342 | len = FFMIN(max_packet_size, size); |
||
343 | |||
344 | /* copy data */ |
||
345 | memcpy(s->buf_ptr, buf1, len); |
||
346 | s->buf_ptr += len; |
||
347 | buf1 += len; |
||
348 | size -= len; |
||
349 | s->timestamp = s->cur_timestamp + n * 8 / sample_size_bits; |
||
350 | ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); |
||
351 | n += (s->buf_ptr - s->buf); |
||
352 | } |
||
353 | return 0; |
||
354 | } |
||
355 | |||
356 | static void rtp_send_mpegaudio(AVFormatContext *s1, |
||
357 | const uint8_t *buf1, int size) |
||
358 | { |
||
359 | RTPMuxContext *s = s1->priv_data; |
||
360 | int len, count, max_packet_size; |
||
361 | |||
362 | max_packet_size = s->max_payload_size; |
||
363 | |||
364 | /* test if we must flush because not enough space */ |
||
365 | len = (s->buf_ptr - s->buf); |
||
366 | if ((len + size) > max_packet_size) { |
||
367 | if (len > 4) { |
||
368 | ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); |
||
369 | s->buf_ptr = s->buf + 4; |
||
370 | } |
||
371 | } |
||
372 | if (s->buf_ptr == s->buf + 4) { |
||
373 | s->timestamp = s->cur_timestamp; |
||
374 | } |
||
375 | |||
376 | /* add the packet */ |
||
377 | if (size > max_packet_size) { |
||
378 | /* big packet: fragment */ |
||
379 | count = 0; |
||
380 | while (size > 0) { |
||
381 | len = max_packet_size - 4; |
||
382 | if (len > size) |
||
383 | len = size; |
||
384 | /* build fragmented packet */ |
||
385 | s->buf[0] = 0; |
||
386 | s->buf[1] = 0; |
||
387 | s->buf[2] = count >> 8; |
||
388 | s->buf[3] = count; |
||
389 | memcpy(s->buf + 4, buf1, len); |
||
390 | ff_rtp_send_data(s1, s->buf, len + 4, 0); |
||
391 | size -= len; |
||
392 | buf1 += len; |
||
393 | count += len; |
||
394 | } |
||
395 | } else { |
||
396 | if (s->buf_ptr == s->buf + 4) { |
||
397 | /* no fragmentation possible */ |
||
398 | s->buf[0] = 0; |
||
399 | s->buf[1] = 0; |
||
400 | s->buf[2] = 0; |
||
401 | s->buf[3] = 0; |
||
402 | } |
||
403 | memcpy(s->buf_ptr, buf1, size); |
||
404 | s->buf_ptr += size; |
||
405 | } |
||
406 | } |
||
407 | |||
408 | static void rtp_send_raw(AVFormatContext *s1, |
||
409 | const uint8_t *buf1, int size) |
||
410 | { |
||
411 | RTPMuxContext *s = s1->priv_data; |
||
412 | int len, max_packet_size; |
||
413 | |||
414 | max_packet_size = s->max_payload_size; |
||
415 | |||
416 | while (size > 0) { |
||
417 | len = max_packet_size; |
||
418 | if (len > size) |
||
419 | len = size; |
||
420 | |||
421 | s->timestamp = s->cur_timestamp; |
||
422 | ff_rtp_send_data(s1, buf1, len, (len == size)); |
||
423 | |||
424 | buf1 += len; |
||
425 | size -= len; |
||
426 | } |
||
427 | } |
||
428 | |||
429 | /* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */ |
||
430 | static void rtp_send_mpegts_raw(AVFormatContext *s1, |
||
431 | const uint8_t *buf1, int size) |
||
432 | { |
||
433 | RTPMuxContext *s = s1->priv_data; |
||
434 | int len, out_len; |
||
435 | |||
436 | while (size >= TS_PACKET_SIZE) { |
||
437 | len = s->max_payload_size - (s->buf_ptr - s->buf); |
||
438 | if (len > size) |
||
439 | len = size; |
||
440 | memcpy(s->buf_ptr, buf1, len); |
||
441 | buf1 += len; |
||
442 | size -= len; |
||
443 | s->buf_ptr += len; |
||
444 | |||
445 | out_len = s->buf_ptr - s->buf; |
||
446 | if (out_len >= s->max_payload_size) { |
||
447 | ff_rtp_send_data(s1, s->buf, out_len, 0); |
||
448 | s->buf_ptr = s->buf; |
||
449 | } |
||
450 | } |
||
451 | } |
||
452 | |||
453 | static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size) |
||
454 | { |
||
455 | RTPMuxContext *s = s1->priv_data; |
||
456 | AVStream *st = s1->streams[0]; |
||
457 | int frame_duration = av_get_audio_frame_duration(st->codec, 0); |
||
458 | int frame_size = st->codec->block_align; |
||
459 | int frames = size / frame_size; |
||
460 | |||
461 | while (frames > 0) { |
||
462 | int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames); |
||
463 | |||
464 | if (!s->num_frames) { |
||
465 | s->buf_ptr = s->buf; |
||
466 | s->timestamp = s->cur_timestamp; |
||
467 | } |
||
468 | memcpy(s->buf_ptr, buf, n * frame_size); |
||
469 | frames -= n; |
||
470 | s->num_frames += n; |
||
471 | s->buf_ptr += n * frame_size; |
||
472 | buf += n * frame_size; |
||
473 | s->cur_timestamp += n * frame_duration; |
||
474 | |||
475 | if (s->num_frames == s->max_frames_per_packet) { |
||
476 | ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1); |
||
477 | s->num_frames = 0; |
||
478 | } |
||
479 | } |
||
480 | return 0; |
||
481 | } |
||
482 | |||
483 | static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) |
||
484 | { |
||
485 | RTPMuxContext *s = s1->priv_data; |
||
486 | AVStream *st = s1->streams[0]; |
||
487 | int rtcp_bytes; |
||
488 | int size= pkt->size; |
||
489 | |||
490 | av_dlog(s1, "%d: write len=%d\n", pkt->stream_index, size); |
||
491 | |||
492 | rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / |
||
493 | RTCP_TX_RATIO_DEN; |
||
494 | if ((s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && |
||
495 | (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) && |
||
496 | !(s->flags & FF_RTP_FLAG_SKIP_RTCP)) { |
||
497 | rtcp_send_sr(s1, ff_ntp_time()); |
||
498 | s->last_octet_count = s->octet_count; |
||
499 | s->first_packet = 0; |
||
500 | } |
||
501 | s->cur_timestamp = s->base_timestamp + pkt->pts; |
||
502 | |||
503 | switch(st->codec->codec_id) { |
||
504 | case AV_CODEC_ID_PCM_MULAW: |
||
505 | case AV_CODEC_ID_PCM_ALAW: |
||
506 | case AV_CODEC_ID_PCM_U8: |
||
507 | case AV_CODEC_ID_PCM_S8: |
||
508 | return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels); |
||
509 | case AV_CODEC_ID_PCM_U16BE: |
||
510 | case AV_CODEC_ID_PCM_U16LE: |
||
511 | case AV_CODEC_ID_PCM_S16BE: |
||
512 | case AV_CODEC_ID_PCM_S16LE: |
||
513 | return rtp_send_samples(s1, pkt->data, size, 16 * st->codec->channels); |
||
514 | case AV_CODEC_ID_ADPCM_G722: |
||
515 | /* The actual sample size is half a byte per sample, but since the |
||
516 | * stream clock rate is 8000 Hz while the sample rate is 16000 Hz, |
||
517 | * the correct parameter for send_samples_bits is 8 bits per stream |
||
518 | * clock. */ |
||
519 | return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels); |
||
520 | case AV_CODEC_ID_ADPCM_G726: |
||
521 | return rtp_send_samples(s1, pkt->data, size, |
||
522 | st->codec->bits_per_coded_sample * st->codec->channels); |
||
523 | case AV_CODEC_ID_MP2: |
||
524 | case AV_CODEC_ID_MP3: |
||
525 | rtp_send_mpegaudio(s1, pkt->data, size); |
||
526 | break; |
||
527 | case AV_CODEC_ID_MPEG1VIDEO: |
||
528 | case AV_CODEC_ID_MPEG2VIDEO: |
||
529 | ff_rtp_send_mpegvideo(s1, pkt->data, size); |
||
530 | break; |
||
531 | case AV_CODEC_ID_AAC: |
||
532 | if (s->flags & FF_RTP_FLAG_MP4A_LATM) |
||
533 | ff_rtp_send_latm(s1, pkt->data, size); |
||
534 | else |
||
535 | ff_rtp_send_aac(s1, pkt->data, size); |
||
536 | break; |
||
537 | case AV_CODEC_ID_AMR_NB: |
||
538 | case AV_CODEC_ID_AMR_WB: |
||
539 | ff_rtp_send_amr(s1, pkt->data, size); |
||
540 | break; |
||
541 | case AV_CODEC_ID_MPEG2TS: |
||
542 | rtp_send_mpegts_raw(s1, pkt->data, size); |
||
543 | break; |
||
544 | case AV_CODEC_ID_H264: |
||
545 | ff_rtp_send_h264(s1, pkt->data, size); |
||
546 | break; |
||
547 | case AV_CODEC_ID_H263: |
||
548 | if (s->flags & FF_RTP_FLAG_RFC2190) { |
||
549 | int mb_info_size = 0; |
||
550 | const uint8_t *mb_info = |
||
551 | av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, |
||
552 | &mb_info_size); |
||
553 | ff_rtp_send_h263_rfc2190(s1, pkt->data, size, mb_info, mb_info_size); |
||
554 | break; |
||
555 | } |
||
556 | /* Fallthrough */ |
||
557 | case AV_CODEC_ID_H263P: |
||
558 | ff_rtp_send_h263(s1, pkt->data, size); |
||
559 | break; |
||
560 | case AV_CODEC_ID_VORBIS: |
||
561 | case AV_CODEC_ID_THEORA: |
||
562 | ff_rtp_send_xiph(s1, pkt->data, size); |
||
563 | break; |
||
564 | case AV_CODEC_ID_VP8: |
||
565 | ff_rtp_send_vp8(s1, pkt->data, size); |
||
566 | break; |
||
567 | case AV_CODEC_ID_ILBC: |
||
568 | rtp_send_ilbc(s1, pkt->data, size); |
||
569 | break; |
||
570 | case AV_CODEC_ID_MJPEG: |
||
571 | ff_rtp_send_jpeg(s1, pkt->data, size); |
||
572 | break; |
||
573 | case AV_CODEC_ID_OPUS: |
||
574 | if (size > s->max_payload_size) { |
||
575 | av_log(s1, AV_LOG_ERROR, |
||
576 | "Packet size %d too large for max RTP payload size %d\n", |
||
577 | size, s->max_payload_size); |
||
578 | return AVERROR(EINVAL); |
||
579 | } |
||
580 | /* Intentional fallthrough */ |
||
581 | default: |
||
582 | /* better than nothing : send the codec raw data */ |
||
583 | rtp_send_raw(s1, pkt->data, size); |
||
584 | break; |
||
585 | } |
||
586 | return 0; |
||
587 | } |
||
588 | |||
589 | static int rtp_write_trailer(AVFormatContext *s1) |
||
590 | { |
||
591 | RTPMuxContext *s = s1->priv_data; |
||
592 | |||
593 | av_freep(&s->buf); |
||
594 | |||
595 | return 0; |
||
596 | } |
||
597 | |||
598 | AVOutputFormat ff_rtp_muxer = { |
||
599 | .name = "rtp", |
||
600 | .long_name = NULL_IF_CONFIG_SMALL("RTP output"), |
||
601 | .priv_data_size = sizeof(RTPMuxContext), |
||
602 | .audio_codec = AV_CODEC_ID_PCM_MULAW, |
||
603 | .video_codec = AV_CODEC_ID_MPEG4, |
||
604 | .write_header = rtp_write_header, |
||
605 | .write_packet = rtp_write_packet, |
||
606 | .write_trailer = rtp_write_trailer, |
||
607 | .priv_class = &rtp_muxer_class, |
||
608 | };><>><>><>><>>=>>>> |