comparison rtsp.c @ 1419:8fb4910bdcc0 libavformat

Add support for H264 over RTP Patch by Ryan Martell % rdm4 A martellventures P com % Original thread: Date: Oct 9, 2006 4:55 PM Subject: [Ffmpeg-devel] RTP patches & RFC Actual committed patch: Date: Oct 26, 2006 4:29 PM
author gpoirier
date Thu, 26 Oct 2006 18:36:03 +0000
parents 0899bfe4105c
children 1c39ce5c6a5d
comparison
equal deleted inserted replaced
1418:9720274e2621 1419:8fb4910bdcc0
28 # include <arpa/inet.h> 28 # include <arpa/inet.h>
29 #else 29 #else
30 # include "barpainet.h" 30 # include "barpainet.h"
31 #endif 31 #endif
32 32
33 #include "rtp_internal.h"
34
33 //#define DEBUG 35 //#define DEBUG
34 //#define DEBUG_RTP_TCP 36 //#define DEBUG_RTP_TCP
35 37
36 enum RTSPClientState { 38 enum RTSPClientState {
37 RTSP_STATE_IDLE, 39 RTSP_STATE_IDLE,
67 int sdp_port; /* port (from SDP content - not used in RTSP) */ 69 int sdp_port; /* port (from SDP content - not used in RTSP) */
68 struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */ 70 struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */
69 int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */ 71 int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */
70 int sdp_payload_type; /* payload type - only used in SDP */ 72 int sdp_payload_type; /* payload type - only used in SDP */
71 rtp_payload_data_t rtp_payload_data; /* rtp payload parsing infos from SDP */ 73 rtp_payload_data_t rtp_payload_data; /* rtp payload parsing infos from SDP */
74
75 RTPDynamicProtocolHandler *dynamic_handler; ///< Only valid if it's a dynamic protocol. (This is the handler structure)
76 void *dynamic_protocol_context; ///< Only valid if it's a dynamic protocol. (This is any private data associated with the dynamic protocol)
72 } RTSPStream; 77 } RTSPStream;
73 78
74 static int rtsp_read_play(AVFormatContext *s); 79 static int rtsp_read_play(AVFormatContext *s);
75 80
76 /* XXX: currently, the only way to change the protocols consists in 81 /* XXX: currently, the only way to change the protocols consists in
140 *pp = p; 145 *pp = p;
141 } 146 }
142 147
143 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other 148 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other
144 params>] */ 149 params>] */
145 static int sdp_parse_rtpmap(AVCodecContext *codec, int payload_type, const char *p) 150 static int sdp_parse_rtpmap(AVCodecContext *codec, RTSPStream *rtsp_st, int payload_type, const char *p)
146 { 151 {
147 char buf[256]; 152 char buf[256];
148 int i; 153 int i;
149 AVCodec *c; 154 AVCodec *c;
150 const char *c_name; 155 const char *c_name;
151 156
152 /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and 157 /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
153 see if we can handle this kind of payload */ 158 see if we can handle this kind of payload */
154 get_word_sep(buf, sizeof(buf), "/", &p); 159 get_word_sep(buf, sizeof(buf), "/", &p);
155 if (payload_type >= RTP_PT_PRIVATE) { 160 if (payload_type >= RTP_PT_PRIVATE) {
156 /* We are in dynmaic payload type case ... search into AVRtpDynamicPayloadTypes[] */ 161 RTPDynamicProtocolHandler *handler= RTPFirstDynamicPayloadHandler;
157 for (i = 0; AVRtpDynamicPayloadTypes[i].codec_id != CODEC_ID_NONE; ++i) 162 while(handler) {
158 if (!strcmp(buf, AVRtpDynamicPayloadTypes[i].enc_name) && (codec->codec_type == AVRtpDynamicPayloadTypes[i].codec_type)) { 163 if (!strcmp(buf, handler->enc_name) && (codec->codec_type == handler->codec_type)) {
159 codec->codec_id = AVRtpDynamicPayloadTypes[i].codec_id; 164 codec->codec_id = handler->codec_id;
165 rtsp_st->dynamic_handler= handler;
166 if(handler->open) {
167 rtsp_st->dynamic_protocol_context= handler->open();
168 }
160 break; 169 break;
161 } 170 }
171 handler= handler->next;
172 }
162 } else { 173 } else {
163 /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */ 174 /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */
164 /* search into AVRtpPayloadTypes[] */ 175 /* search into AVRtpPayloadTypes[] */
165 for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i) 176 for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
166 if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec->codec_type == AVRtpPayloadTypes[i].codec_type)){ 177 if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec->codec_type == AVRtpPayloadTypes[i].codec_type)){
438 payload_type = atoi(buf1); 449 payload_type = atoi(buf1);
439 for(i = 0; i < s->nb_streams;i++) { 450 for(i = 0; i < s->nb_streams;i++) {
440 st = s->streams[i]; 451 st = s->streams[i];
441 rtsp_st = st->priv_data; 452 rtsp_st = st->priv_data;
442 if (rtsp_st->sdp_payload_type == payload_type) { 453 if (rtsp_st->sdp_payload_type == payload_type) {
443 sdp_parse_rtpmap(st->codec, payload_type, p); 454 sdp_parse_rtpmap(st->codec, rtsp_st, payload_type, p);
444 } 455 }
445 } 456 }
446 } else if (strstart(p, "fmtp:", &p)) { 457 } else if (strstart(p, "fmtp:", &p)) {
447 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ 458 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
448 get_word(buf1, sizeof(buf1), &p); 459 get_word(buf1, sizeof(buf1), &p);
449 payload_type = atoi(buf1); 460 payload_type = atoi(buf1);
450 for(i = 0; i < s->nb_streams;i++) { 461 for(i = 0; i < s->nb_streams;i++) {
451 st = s->streams[i]; 462 st = s->streams[i];
452 rtsp_st = st->priv_data; 463 rtsp_st = st->priv_data;
453 if (rtsp_st->sdp_payload_type == payload_type) { 464 if (rtsp_st->sdp_payload_type == payload_type) {
465 if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) {
466 if(!rtsp_st->dynamic_handler->parse_sdp_a_line(st, rtsp_st->dynamic_protocol_context, buf)) {
467 sdp_parse_fmtp(st, p);
468 }
469 } else {
454 sdp_parse_fmtp(st, p); 470 sdp_parse_fmtp(st, p);
471 }
455 } 472 }
456 } 473 }
457 } 474 }
458 break; 475 break;
459 } 476 }
786 if (rtsp_st) { 803 if (rtsp_st) {
787 if (rtsp_st->rtp_ctx) 804 if (rtsp_st->rtp_ctx)
788 rtp_parse_close(rtsp_st->rtp_ctx); 805 rtp_parse_close(rtsp_st->rtp_ctx);
789 if (rtsp_st->rtp_handle) 806 if (rtsp_st->rtp_handle)
790 url_close(rtsp_st->rtp_handle); 807 url_close(rtsp_st->rtp_handle);
808 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
809 rtsp_st->dynamic_handler->close(rtsp_st->dynamic_protocol_context);
791 } 810 }
792 av_free(rtsp_st); 811 av_free(rtsp_st);
793 } 812 }
794 av_free(rt->rtsp_streams); 813 av_free(rt->rtsp_streams);
795 } 814 }
978 rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data); 997 rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data);
979 998
980 if (!rtsp_st->rtp_ctx) { 999 if (!rtsp_st->rtp_ctx) {
981 err = AVERROR_NOMEM; 1000 err = AVERROR_NOMEM;
982 goto fail; 1001 goto fail;
1002 } else {
1003 if(rtsp_st->dynamic_handler) {
1004 rtsp_st->rtp_ctx->dynamic_protocol_context= rtsp_st->dynamic_protocol_context;
1005 rtsp_st->rtp_ctx->parse_packet= rtsp_st->dynamic_handler->parse_packet;
1006 }
983 } 1007 }
984 } 1008 }
985 1009
986 /* use callback if available to extend setup */ 1010 /* use callback if available to extend setup */
987 if (ff_rtsp_callback) { 1011 if (ff_rtsp_callback) {
1324 s->ctx_flags |= AVFMTCTX_NOHEADER; 1348 s->ctx_flags |= AVFMTCTX_NOHEADER;
1325 rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data); 1349 rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data);
1326 if (!rtsp_st->rtp_ctx) { 1350 if (!rtsp_st->rtp_ctx) {
1327 err = AVERROR_NOMEM; 1351 err = AVERROR_NOMEM;
1328 goto fail; 1352 goto fail;
1353 } else {
1354 if(rtsp_st->dynamic_handler) {
1355 rtsp_st->rtp_ctx->dynamic_protocol_context= rtsp_st->dynamic_protocol_context;
1356 rtsp_st->rtp_ctx->parse_packet= rtsp_st->dynamic_handler->parse_packet;
1357 }
1329 } 1358 }
1330 } 1359 }
1331 return 0; 1360 return 0;
1332 fail: 1361 fail:
1333 rtsp_close_streams(rt); 1362 rtsp_close_streams(rt);