Mercurial > libavformat.hg
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); |