OLD | NEW |
1 /* | 1 /* |
2 * RTP input format | 2 * RTP input format |
3 * Copyright (c) 2002 Fabrice Bellard | 3 * Copyright (c) 2002 Fabrice Bellard |
4 * | 4 * |
5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
6 * | 6 * |
7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
(...skipping 12 matching lines...) Expand all Loading... |
23 #define _XOPEN_SOURCE 600 | 23 #define _XOPEN_SOURCE 600 |
24 | 24 |
25 #include "libavcodec/get_bits.h" | 25 #include "libavcodec/get_bits.h" |
26 #include "avformat.h" | 26 #include "avformat.h" |
27 #include "mpegts.h" | 27 #include "mpegts.h" |
28 | 28 |
29 #include <unistd.h> | 29 #include <unistd.h> |
30 #include "network.h" | 30 #include "network.h" |
31 | 31 |
32 #include "rtpdec.h" | 32 #include "rtpdec.h" |
33 #include "rtp_asf.h" | 33 #include "rtpdec_amr.h" |
34 #include "rtp_h264.h" | 34 #include "rtpdec_asf.h" |
35 #include "rtp_vorbis.h" | |
36 #include "rtpdec_h263.h" | 35 #include "rtpdec_h263.h" |
| 36 #include "rtpdec_h264.h" |
| 37 #include "rtpdec_vorbis.h" |
37 | 38 |
38 //#define DEBUG | 39 //#define DEBUG |
39 | 40 |
40 /* TODO: - add RTCP statistics reporting (should be optional). | 41 /* TODO: - add RTCP statistics reporting (should be optional). |
41 | 42 |
42 - add support for h263/mpeg4 packetized output : IDEA: send a | 43 - add support for h263/mpeg4 packetized output : IDEA: send a |
43 buffer to 'rtp_write_packet' contains all the packets for ONE | 44 buffer to 'rtp_write_packet' contains all the packets for ONE |
44 frame. Each packet should have a four byte header containing | 45 frame. Each packet should have a four byte header containing |
45 the length in big endian format (same trick as | 46 the length in big endian format (same trick as |
46 'url_open_dyn_packet_buf') | 47 'url_open_dyn_packet_buf') |
47 */ | 48 */ |
48 | 49 |
49 /* statistics functions */ | 50 /* statistics functions */ |
50 RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL; | 51 RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL; |
51 | 52 |
52 static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", CODEC_TYPE_VIDEO,
CODEC_ID_MPEG4}; | 53 static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", CODEC_TYPE_VIDEO,
CODEC_ID_MPEG4}; |
53 static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", CODEC_
TYPE_AUDIO, CODEC_ID_AAC}; | 54 static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", CODEC_
TYPE_AUDIO, CODEC_ID_AAC}; |
54 | 55 |
55 void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler) | 56 void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler) |
56 { | 57 { |
57 handler->next= RTPFirstDynamicPayloadHandler; | 58 handler->next= RTPFirstDynamicPayloadHandler; |
58 RTPFirstDynamicPayloadHandler= handler; | 59 RTPFirstDynamicPayloadHandler= handler; |
59 } | 60 } |
60 | 61 |
61 void av_register_rtp_dynamic_payload_handlers(void) | 62 void av_register_rtp_dynamic_payload_handlers(void) |
62 { | 63 { |
63 ff_register_dynamic_payload_handler(&mp4v_es_handler); | 64 ff_register_dynamic_payload_handler(&mp4v_es_handler); |
64 ff_register_dynamic_payload_handler(&mpeg4_generic_handler); | 65 ff_register_dynamic_payload_handler(&mpeg4_generic_handler); |
| 66 ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler); |
| 67 ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler); |
65 ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler); | 68 ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler); |
66 ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); | 69 ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); |
67 ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); | 70 ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); |
68 ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler); | 71 ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler); |
69 | 72 |
70 ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler); | 73 ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler); |
71 ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler); | 74 ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler); |
72 } | 75 } |
73 | 76 |
74 static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
en) | 77 static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
en) |
75 { | 78 { |
76 if (buf[1] != 200) | 79 if (buf[1] != 200) |
77 return -1; | 80 return -1; |
78 s->last_rtcp_ntp_time = AV_RB64(buf + 8); | 81 s->last_rtcp_ntp_time = AV_RB64(buf + 8); |
79 if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) | |
80 s->first_rtcp_ntp_time = s->last_rtcp_ntp_time; | |
81 s->last_rtcp_timestamp = AV_RB32(buf + 16); | 82 s->last_rtcp_timestamp = AV_RB32(buf + 16); |
82 return 0; | 83 return 0; |
83 } | 84 } |
84 | 85 |
85 #define RTP_SEQ_MOD (1<<16) | 86 #define RTP_SEQ_MOD (1<<16) |
86 | 87 |
87 /** | 88 /** |
88 * called on parse open packet | 89 * called on parse open packet |
89 */ | 90 */ |
90 static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // cal
led on parse open packet. | 91 static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // cal
led on parse open packet. |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 if ((len > 0) && buf) { | 264 if ((len > 0) && buf) { |
264 int result; | 265 int result; |
265 dprintf(s->ic, "sending %d bytes of RR\n", len); | 266 dprintf(s->ic, "sending %d bytes of RR\n", len); |
266 result= url_write(s->rtp_ctx, buf, len); | 267 result= url_write(s->rtp_ctx, buf, len); |
267 dprintf(s->ic, "result from url_write: %d\n", result); | 268 dprintf(s->ic, "result from url_write: %d\n", result); |
268 av_free(buf); | 269 av_free(buf); |
269 } | 270 } |
270 return 0; | 271 return 0; |
271 } | 272 } |
272 | 273 |
| 274 void rtp_send_punch_packets(URLContext* rtp_handle) |
| 275 { |
| 276 ByteIOContext *pb; |
| 277 uint8_t *buf; |
| 278 int len; |
| 279 |
| 280 /* Send a small RTP packet */ |
| 281 if (url_open_dyn_buf(&pb) < 0) |
| 282 return; |
| 283 |
| 284 put_byte(pb, (RTP_VERSION << 6)); |
| 285 put_byte(pb, 0); /* Payload type */ |
| 286 put_be16(pb, 0); /* Seq */ |
| 287 put_be32(pb, 0); /* Timestamp */ |
| 288 put_be32(pb, 0); /* SSRC */ |
| 289 |
| 290 put_flush_packet(pb); |
| 291 len = url_close_dyn_buf(pb, &buf); |
| 292 if ((len > 0) && buf) |
| 293 url_write(rtp_handle, buf, len); |
| 294 av_free(buf); |
| 295 |
| 296 /* Send a minimal RTCP RR */ |
| 297 if (url_open_dyn_buf(&pb) < 0) |
| 298 return; |
| 299 |
| 300 put_byte(pb, (RTP_VERSION << 6)); |
| 301 put_byte(pb, 201); /* receiver report */ |
| 302 put_be16(pb, 1); /* length in words - 1 */ |
| 303 put_be32(pb, 0); /* our own SSRC */ |
| 304 |
| 305 put_flush_packet(pb); |
| 306 len = url_close_dyn_buf(pb, &buf); |
| 307 if ((len > 0) && buf) |
| 308 url_write(rtp_handle, buf, len); |
| 309 av_free(buf); |
| 310 } |
| 311 |
| 312 |
273 /** | 313 /** |
274 * open a new RTP parse context for stream 'st'. 'st' can be NULL for | 314 * open a new RTP parse context for stream 'st'. 'st' can be NULL for |
275 * MPEG2TS streams to indicate that they should be demuxed inside the | 315 * MPEG2TS streams to indicate that they should be demuxed inside the |
276 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned) | 316 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned) |
277 * TODO: change this to not take rtp_payload data, and use the new dynamic paylo
ad system. | 317 * TODO: change this to not take rtp_payload data, and use the new dynamic paylo
ad system. |
278 */ | 318 */ |
279 RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r
tpc, int payload_type, RTPPayloadData *rtp_payload_data) | 319 RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r
tpc, int payload_type, RTPPayloadData *rtp_payload_data) |
280 { | 320 { |
281 RTPDemuxContext *s; | 321 RTPDemuxContext *s; |
282 | 322 |
283 s = av_mallocz(sizeof(RTPDemuxContext)); | 323 s = av_mallocz(sizeof(RTPDemuxContext)); |
284 if (!s) | 324 if (!s) |
285 return NULL; | 325 return NULL; |
286 s->payload_type = payload_type; | 326 s->payload_type = payload_type; |
287 s->last_rtcp_ntp_time = AV_NOPTS_VALUE; | 327 s->last_rtcp_ntp_time = AV_NOPTS_VALUE; |
288 s->first_rtcp_ntp_time = AV_NOPTS_VALUE; | |
289 s->ic = s1; | 328 s->ic = s1; |
290 s->st = st; | 329 s->st = st; |
291 s->rtp_payload_data = rtp_payload_data; | 330 s->rtp_payload_data = rtp_payload_data; |
292 rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence f
rom sdp? | 331 rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence f
rom sdp? |
293 if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) { | 332 if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) { |
294 s->ts = ff_mpegts_parse_open(s->ic); | 333 s->ts = ff_mpegts_parse_open(s->ic); |
295 if (s->ts == NULL) { | 334 if (s->ts == NULL) { |
296 av_free(s); | 335 av_free(s); |
297 return NULL; | 336 return NULL; |
298 } | 337 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 */ | 421 */ |
383 static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
p) | 422 static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
p) |
384 { | 423 { |
385 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { | 424 if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { |
386 int64_t addend; | 425 int64_t addend; |
387 int delta_timestamp; | 426 int delta_timestamp; |
388 | 427 |
389 /* compute pts from timestamp with received ntp_time */ | 428 /* compute pts from timestamp with received ntp_time */ |
390 delta_timestamp = timestamp - s->last_rtcp_timestamp; | 429 delta_timestamp = timestamp - s->last_rtcp_timestamp; |
391 /* convert to the PTS timebase */ | 430 /* convert to the PTS timebase */ |
392 addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->s
t->time_base.den, (uint64_t)s->st->time_base.num << 32); | 431 addend = av_rescale(s->last_rtcp_ntp_time, s->st->time_base.den, (uint64
_t)s->st->time_base.num << 32); |
393 pkt->pts = addend + delta_timestamp; | 432 pkt->pts = addend + delta_timestamp; |
394 } | 433 } |
395 } | 434 } |
396 | 435 |
397 /** | 436 /** |
398 * Parse an RTP or RTCP packet directly sent as a buffer. | 437 * Parse an RTP or RTCP packet directly sent as a buffer. |
399 * @param s RTP parse context. | 438 * @param s RTP parse context. |
400 * @param pkt returned packet | 439 * @param pkt returned packet |
401 * @param buf input buffer or NULL to read the next packets | 440 * @param buf input buffer or NULL to read the next packets |
402 * @param len buffer len | 441 * @param len buffer len |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 } | 596 } |
558 | 597 |
559 void rtp_parse_close(RTPDemuxContext *s) | 598 void rtp_parse_close(RTPDemuxContext *s) |
560 { | 599 { |
561 // TODO: fold this into the protocol specific data fields. | 600 // TODO: fold this into the protocol specific data fields. |
562 if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) { | 601 if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) { |
563 ff_mpegts_parse_close(s->ts); | 602 ff_mpegts_parse_close(s->ts); |
564 } | 603 } |
565 av_free(s); | 604 av_free(s); |
566 } | 605 } |
OLD | NEW |