Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: source/patched-ffmpeg-mt/libavformat/rtsp.c

Issue 4533003: patched ffmpeg nov 2 (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * RTSP/SDP client 2 * RTSP/SDP client
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 26 matching lines...) Expand all
37 #include "rtsp.h" 37 #include "rtsp.h"
38 38
39 #include "rtpdec.h" 39 #include "rtpdec.h"
40 #include "rdt.h" 40 #include "rdt.h"
41 #include "rtpdec_formats.h" 41 #include "rtpdec_formats.h"
42 #include "rtpenc_chain.h" 42 #include "rtpenc_chain.h"
43 43
44 //#define DEBUG 44 //#define DEBUG
45 //#define DEBUG_RTP_TCP 45 //#define DEBUG_RTP_TCP
46 46
47 #if LIBAVFORMAT_VERSION_INT < (53 << 16)
48 int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP);
49 #endif
50
51 /* Timeout values for socket select, in ms, 47 /* Timeout values for socket select, in ms,
52 * and read_packet(), in seconds */ 48 * and read_packet(), in seconds */
53 #define SELECT_TIMEOUT_MS 100 49 #define SELECT_TIMEOUT_MS 100
54 #define READ_PACKET_TIMEOUT_S 10 50 #define READ_PACKET_TIMEOUT_S 10
55 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS 51 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS
56 #define SDP_MAX_SIZE 16384 52 #define SDP_MAX_SIZE 16384
57 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH 53 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
58 54
59 static void get_word_until_chars(char *buf, int buf_size, 55 static void get_word_until_chars(char *buf, int buf_size,
60 const char *sep, const char **pp) 56 const char *sep, const char **pp)
(...skipping 19 matching lines...) Expand all
80 { 76 {
81 if (**pp == '/') (*pp)++; 77 if (**pp == '/') (*pp)++;
82 get_word_until_chars(buf, buf_size, sep, pp); 78 get_word_until_chars(buf, buf_size, sep, pp);
83 } 79 }
84 80
85 static void get_word(char *buf, int buf_size, const char **pp) 81 static void get_word(char *buf, int buf_size, const char **pp)
86 { 82 {
87 get_word_until_chars(buf, buf_size, SPACE_CHARS, pp); 83 get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
88 } 84 }
89 85
86 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
87 * and end time.
88 * Used for seeking in the rtp stream.
89 */
90 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
91 {
92 char buf[256];
93
94 p += strspn(p, SPACE_CHARS);
95 if (!av_stristart(p, "npt=", &p))
96 return;
97
98 *start = AV_NOPTS_VALUE;
99 *end = AV_NOPTS_VALUE;
100
101 get_word_sep(buf, sizeof(buf), "-", &p);
102 *start = parse_date(buf, 1);
103 if (*p == '-') {
104 p++;
105 get_word_sep(buf, sizeof(buf), "-", &p);
106 *end = parse_date(buf, 1);
107 }
108 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
109 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
110 }
111
112 static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
113 {
114 struct addrinfo hints, *ai = NULL;
115 memset(&hints, 0, sizeof(hints));
116 hints.ai_flags = AI_NUMERICHOST;
117 if (getaddrinfo(buf, NULL, &hints, &ai))
118 return -1;
119 memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
120 freeaddrinfo(ai);
121 return 0;
122 }
123
124 #if CONFIG_RTPDEC
90 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */ 125 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
91 static int sdp_parse_rtpmap(AVFormatContext *s, 126 static int sdp_parse_rtpmap(AVFormatContext *s,
92 AVCodecContext *codec, RTSPStream *rtsp_st, 127 AVCodecContext *codec, RTSPStream *rtsp_st,
93 int payload_type, const char *p) 128 int payload_type, const char *p)
94 { 129 {
95 char buf[256]; 130 char buf[256];
96 int i; 131 int i;
97 AVCodec *c; 132 AVCodec *c;
98 const char *c_name; 133 const char *c_name;
99 134
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 if (**p == '=') 214 if (**p == '=')
180 (*p)++; 215 (*p)++;
181 get_word_sep(value, value_size, ";", p); 216 get_word_sep(value, value_size, ";", p);
182 if (**p == ';') 217 if (**p == ';')
183 (*p)++; 218 (*p)++;
184 return 1; 219 return 1;
185 } 220 }
186 return 0; 221 return 0;
187 } 222 }
188 223
189 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
190 * and end time.
191 * Used for seeking in the rtp stream.
192 */
193 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
194 {
195 char buf[256];
196
197 p += strspn(p, SPACE_CHARS);
198 if (!av_stristart(p, "npt=", &p))
199 return;
200
201 *start = AV_NOPTS_VALUE;
202 *end = AV_NOPTS_VALUE;
203
204 get_word_sep(buf, sizeof(buf), "-", &p);
205 *start = parse_date(buf, 1);
206 if (*p == '-') {
207 p++;
208 get_word_sep(buf, sizeof(buf), "-", &p);
209 *end = parse_date(buf, 1);
210 }
211 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
212 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
213 }
214
215 static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
216 {
217 struct addrinfo hints, *ai = NULL;
218 memset(&hints, 0, sizeof(hints));
219 hints.ai_flags = AI_NUMERICHOST;
220 if (getaddrinfo(buf, NULL, &hints, &ai))
221 return -1;
222 memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
223 freeaddrinfo(ai);
224 return 0;
225 }
226
227 typedef struct SDPParseState { 224 typedef struct SDPParseState {
228 /* SDP only */ 225 /* SDP only */
229 struct sockaddr_storage default_ip; 226 struct sockaddr_storage default_ip;
230 int default_ttl; 227 int default_ttl;
231 int skip_media; ///< set if an unknown m= line occurs 228 int skip_media; ///< set if an unknown m= line occurs
232 } SDPParseState; 229 } SDPParseState;
233 230
234 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, 231 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
235 int letter, const char *buf) 232 int letter, const char *buf)
236 { 233 {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 *q = '\0'; 447 *q = '\0';
451 sdp_parse_line(s, s1, letter, buf); 448 sdp_parse_line(s, s1, letter, buf);
452 next_line: 449 next_line:
453 while (*p != '\n' && *p != '\0') 450 while (*p != '\n' && *p != '\0')
454 p++; 451 p++;
455 if (*p == '\n') 452 if (*p == '\n')
456 p++; 453 p++;
457 } 454 }
458 return 0; 455 return 0;
459 } 456 }
457 #endif /* CONFIG_RTPDEC */
460 458
461 /* close and free RTSP streams */ 459 /* close and free RTSP streams */
462 void ff_rtsp_close_streams(AVFormatContext *s) 460 void ff_rtsp_close_streams(AVFormatContext *s)
463 { 461 {
464 RTSPState *rt = s->priv_data; 462 RTSPState *rt = s->priv_data;
465 int i; 463 int i;
466 RTSPStream *rtsp_st; 464 RTSPStream *rtsp_st;
467 465
468 for (i = 0; i < rt->nb_rtsp_streams; i++) { 466 for (i = 0; i < rt->nb_rtsp_streams; i++) {
469 rtsp_st = rt->rtsp_streams[i]; 467 rtsp_st = rt->rtsp_streams[i];
470 if (rtsp_st) { 468 if (rtsp_st) {
471 if (rtsp_st->transport_priv) { 469 if (rtsp_st->transport_priv) {
472 if (s->oformat) { 470 if (s->oformat) {
473 AVFormatContext *rtpctx = rtsp_st->transport_priv; 471 AVFormatContext *rtpctx = rtsp_st->transport_priv;
474 av_write_trailer(rtpctx); 472 av_write_trailer(rtpctx);
475 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { 473 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
476 uint8_t *ptr; 474 uint8_t *ptr;
477 url_close_dyn_buf(rtpctx->pb, &ptr); 475 url_close_dyn_buf(rtpctx->pb, &ptr);
478 av_free(ptr); 476 av_free(ptr);
479 } else { 477 } else {
480 url_fclose(rtpctx->pb); 478 url_fclose(rtpctx->pb);
481 } 479 }
482 av_metadata_free(&rtpctx->streams[0]->metadata); 480 av_metadata_free(&rtpctx->streams[0]->metadata);
483 av_metadata_free(&rtpctx->metadata); 481 av_metadata_free(&rtpctx->metadata);
484 av_free(rtpctx->streams[0]); 482 av_free(rtpctx->streams[0]);
485 av_free(rtpctx); 483 av_free(rtpctx);
486 } else if (rt->transport == RTSP_TRANSPORT_RDT) 484 } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
487 ff_rdt_parse_close(rtsp_st->transport_priv); 485 ff_rdt_parse_close(rtsp_st->transport_priv);
488 else 486 else if (CONFIG_RTPDEC)
489 rtp_parse_close(rtsp_st->transport_priv); 487 rtp_parse_close(rtsp_st->transport_priv);
490 } 488 }
491 if (rtsp_st->rtp_handle) 489 if (rtsp_st->rtp_handle)
492 url_close(rtsp_st->rtp_handle); 490 url_close(rtsp_st->rtp_handle);
493 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) 491 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
494 rtsp_st->dynamic_handler->close( 492 rtsp_st->dynamic_handler->close(
495 rtsp_st->dynamic_protocol_context); 493 rtsp_st->dynamic_protocol_context);
496 } 494 }
497 } 495 }
498 av_free(rt->rtsp_streams); 496 av_free(rt->rtsp_streams);
499 if (rt->asf_ctx) { 497 if (rt->asf_ctx) {
500 av_close_input_stream (rt->asf_ctx); 498 av_close_input_stream (rt->asf_ctx);
501 rt->asf_ctx = NULL; 499 rt->asf_ctx = NULL;
502 } 500 }
503 av_free(rt->recvbuf); 501 av_free(rt->recvbuf);
504 } 502 }
505 503
506 static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) 504 static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
507 { 505 {
508 RTSPState *rt = s->priv_data; 506 RTSPState *rt = s->priv_data;
509 AVStream *st = NULL; 507 AVStream *st = NULL;
510 508
511 /* open the RTP context */ 509 /* open the RTP context */
512 if (rtsp_st->stream_index >= 0) 510 if (rtsp_st->stream_index >= 0)
513 st = s->streams[rtsp_st->stream_index]; 511 st = s->streams[rtsp_st->stream_index];
514 if (!st) 512 if (!st)
515 s->ctx_flags |= AVFMTCTX_NOHEADER; 513 s->ctx_flags |= AVFMTCTX_NOHEADER;
516 514
517 if (s->oformat) { 515 if (s->oformat && CONFIG_RTSP_MUXER) {
518 rtsp_st->transport_priv = ff_rtp_chain_mux_open(s, st, 516 rtsp_st->transport_priv = ff_rtp_chain_mux_open(s, st,
519 rtsp_st->rtp_handle, 517 rtsp_st->rtp_handle,
520 RTSP_TCP_MAX_PACKET_SIZE); 518 RTSP_TCP_MAX_PACKET_SIZE);
521 /* Ownership of rtp_handle is passed to the rtp mux context */ 519 /* Ownership of rtp_handle is passed to the rtp mux context */
522 rtsp_st->rtp_handle = NULL; 520 rtsp_st->rtp_handle = NULL;
523 } else if (rt->transport == RTSP_TRANSPORT_RDT) 521 } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
524 rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index, 522 rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
525 rtsp_st->dynamic_protocol_context, 523 rtsp_st->dynamic_protocol_context,
526 rtsp_st->dynamic_handler); 524 rtsp_st->dynamic_handler);
527 else 525 else if (CONFIG_RTPDEC)
528 rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle, 526 rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
529 rtsp_st->sdp_payload_type, 527 rtsp_st->sdp_payload_type,
530 (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay) 528 (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
531 ? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE); 529 ? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
532 530
533 if (!rtsp_st->transport_priv) { 531 if (!rtsp_st->transport_priv) {
534 return AVERROR(ENOMEM); 532 return AVERROR(ENOMEM);
535 } else if (rt->transport != RTSP_TRANSPORT_RDT) { 533 } else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) {
536 if (rtsp_st->dynamic_handler) { 534 if (rtsp_st->dynamic_handler) {
537 rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv, 535 rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
538 rtsp_st->dynamic_protocol_context, 536 rtsp_st->dynamic_protocol_context,
539 rtsp_st->dynamic_handler); 537 rtsp_st->dynamic_handler);
540 } 538 }
541 } 539 }
542 540
543 return 0; 541 return 0;
544 } 542 }
545 543
546 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER 544 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
547 static int rtsp_probe(AVProbeData *p)
548 {
549 if (av_strstart(p->filename, "rtsp:", NULL))
550 return AVPROBE_SCORE_MAX;
551 return 0;
552 }
553
554 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) 545 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
555 { 546 {
556 const char *p; 547 const char *p;
557 int v; 548 int v;
558 549
559 p = *pp; 550 p = *pp;
560 p += strspn(p, SPACE_CHARS); 551 p += strspn(p, SPACE_CHARS);
561 v = strtol(p, (char **)&p, 10); 552 v = strtol(p, (char **)&p, 10);
562 if (*p == '-') { 553 if (*p == '-') {
563 p++; 554 p++;
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 1008
1018 #if 0 1009 #if 0
1019 /* then try on any port */ 1010 /* then try on any port */
1020 if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { 1011 if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
1021 err = AVERROR_INVALIDDATA; 1012 err = AVERROR_INVALIDDATA;
1022 goto fail; 1013 goto fail;
1023 } 1014 }
1024 #endif 1015 #endif
1025 1016
1026 rtp_opened: 1017 rtp_opened:
1027 port = rtp_get_local_port(rtsp_st->rtp_handle); 1018 port = rtp_get_local_rtp_port(rtsp_st->rtp_handle);
1028 have_port: 1019 have_port:
1029 snprintf(transport, sizeof(transport) - 1, 1020 snprintf(transport, sizeof(transport) - 1,
1030 "%s/UDP;", trans_pref); 1021 "%s/UDP;", trans_pref);
1031 if (rt->server_type != RTSP_SERVER_REAL) 1022 if (rt->server_type != RTSP_SERVER_REAL)
1032 av_strlcat(transport, "unicast;", sizeof(transport)); 1023 av_strlcat(transport, "unicast;", sizeof(transport));
1033 av_strlcatf(transport, sizeof(transport), 1024 av_strlcatf(transport, sizeof(transport),
1034 "client_port=%d", port); 1025 "client_port=%d", port);
1035 if (rt->transport == RTSP_TRANSPORT_RTP && 1026 if (rt->transport == RTSP_TRANSPORT_RTP &&
1036 !(rt->server_type == RTSP_SERVER_WMS && i > 0)) 1027 !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1037 av_strlcatf(transport, sizeof(transport), "-%d", port + 1); 1028 av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
(...skipping 23 matching lines...) Expand all
1061 "%s/UDP;multicast", trans_pref); 1052 "%s/UDP;multicast", trans_pref);
1062 } 1053 }
1063 if (s->oformat) { 1054 if (s->oformat) {
1064 av_strlcat(transport, ";mode=receive", sizeof(transport)); 1055 av_strlcat(transport, ";mode=receive", sizeof(transport));
1065 } else if (rt->server_type == RTSP_SERVER_REAL || 1056 } else if (rt->server_type == RTSP_SERVER_REAL ||
1066 rt->server_type == RTSP_SERVER_WMS) 1057 rt->server_type == RTSP_SERVER_WMS)
1067 av_strlcat(transport, ";mode=play", sizeof(transport)); 1058 av_strlcat(transport, ";mode=play", sizeof(transport));
1068 snprintf(cmd, sizeof(cmd), 1059 snprintf(cmd, sizeof(cmd),
1069 "Transport: %s\r\n", 1060 "Transport: %s\r\n",
1070 transport); 1061 transport);
1071 if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { 1062 if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
1072 char real_res[41], real_csum[9]; 1063 char real_res[41], real_csum[9];
1073 ff_rdt_calc_response_and_checksum(real_res, real_csum, 1064 ff_rdt_calc_response_and_checksum(real_res, real_csum,
1074 real_challenge); 1065 real_challenge);
1075 av_strlcatf(cmd, sizeof(cmd), 1066 av_strlcatf(cmd, sizeof(cmd),
1076 "If-Match: %s\r\n" 1067 "If-Match: %s\r\n"
1077 "RealChallenge2: %s, sd=%s\r\n", 1068 "RealChallenge2: %s, sd=%s\r\n",
1078 rt->session_id, real_res, real_csum); 1069 rt->session_id, real_res, real_csum);
1079 } 1070 }
1080 ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL); 1071 ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1081 if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) { 1072 if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 } 1117 }
1127 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && 1118 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1128 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { 1119 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1129 err = AVERROR_INVALIDDATA; 1120 err = AVERROR_INVALIDDATA;
1130 goto fail; 1121 goto fail;
1131 } 1122 }
1132 /* Try to initialize the connection state in a 1123 /* Try to initialize the connection state in a
1133 * potential NAT router by sending dummy packets. 1124 * potential NAT router by sending dummy packets.
1134 * RTP/RTCP dummy packets are used for RDT, too. 1125 * RTP/RTCP dummy packets are used for RDT, too.
1135 */ 1126 */
1136 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat) 1127 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
1128 CONFIG_RTPDEC)
1137 rtp_send_punch_packets(rtsp_st->rtp_handle); 1129 rtp_send_punch_packets(rtsp_st->rtp_handle);
1138 break; 1130 break;
1139 } 1131 }
1140 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { 1132 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
1141 char url[1024], namebuf[50]; 1133 char url[1024], namebuf[50];
1142 struct sockaddr_storage addr; 1134 struct sockaddr_storage addr;
1143 int port, ttl; 1135 int port, ttl;
1144 1136
1145 if (reply->transports[0].destination.ss_family) { 1137 if (reply->transports[0].destination.ss_family) {
1146 addr = reply->transports[0].destination; 1138 addr = reply->transports[0].destination;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 av_rescale_q(reply->range_start, AV_TIME_BASE_Q, 1217 av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
1226 st->time_base); 1218 st->time_base);
1227 } 1219 }
1228 } 1220 }
1229 } 1221 }
1230 } 1222 }
1231 rt->state = RTSP_STATE_STREAMING; 1223 rt->state = RTSP_STATE_STREAMING;
1232 return 0; 1224 return 0;
1233 } 1225 }
1234 1226
1227 #if CONFIG_RTSP_DEMUXER
1235 static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply ) 1228 static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply )
1236 { 1229 {
1237 RTSPState *rt = s->priv_data; 1230 RTSPState *rt = s->priv_data;
1238 char cmd[1024]; 1231 char cmd[1024];
1239 unsigned char *content = NULL; 1232 unsigned char *content = NULL;
1240 int ret; 1233 int ret;
1241 1234
1242 /* describe the stream */ 1235 /* describe the stream */
1243 snprintf(cmd, sizeof(cmd), 1236 snprintf(cmd, sizeof(cmd),
1244 "Accept: application/sdp\r\n"); 1237 "Accept: application/sdp\r\n");
(...skipping 16 matching lines...) Expand all
1261 1254
1262 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content); 1255 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
1263 /* now we got the SDP description, we parse it */ 1256 /* now we got the SDP description, we parse it */
1264 ret = sdp_parse(s, (const char *)content); 1257 ret = sdp_parse(s, (const char *)content);
1265 av_freep(&content); 1258 av_freep(&content);
1266 if (ret < 0) 1259 if (ret < 0)
1267 return AVERROR_INVALIDDATA; 1260 return AVERROR_INVALIDDATA;
1268 1261
1269 return 0; 1262 return 0;
1270 } 1263 }
1264 #endif /* CONFIG_RTSP_DEMUXER */
1271 1265
1266 #if CONFIG_RTSP_MUXER
1272 static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) 1267 static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
1273 { 1268 {
1274 RTSPState *rt = s->priv_data; 1269 RTSPState *rt = s->priv_data;
1275 RTSPMessageHeader reply1, *reply = &reply1; 1270 RTSPMessageHeader reply1, *reply = &reply1;
1276 int i; 1271 int i;
1277 char *sdp; 1272 char *sdp;
1278 AVFormatContext sdp_ctx, *ctx_array[1]; 1273 AVFormatContext sdp_ctx, *ctx_array[1];
1279 1274
1280 s->start_time_realtime = av_gettime(); 1275 s->start_time_realtime = av_gettime();
1281 1276
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 rtsp_st->stream_index = i; 1320 rtsp_st->stream_index = i;
1326 1321
1327 av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->contro l_url)); 1322 av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->contro l_url));
1328 /* Note, this must match the relative uri set in the sdp content */ 1323 /* Note, this must match the relative uri set in the sdp content */
1329 av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url), 1324 av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url),
1330 "/streamid=%d", i); 1325 "/streamid=%d", i);
1331 } 1326 }
1332 1327
1333 return 0; 1328 return 0;
1334 } 1329 }
1330 #endif /* CONFIG_RTSP_MUXER */
1335 1331
1336 void ff_rtsp_close_connections(AVFormatContext *s) 1332 void ff_rtsp_close_connections(AVFormatContext *s)
1337 { 1333 {
1338 RTSPState *rt = s->priv_data; 1334 RTSPState *rt = s->priv_data;
1339 if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out); 1335 if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out);
1340 url_close(rt->rtsp_hd); 1336 url_close(rt->rtsp_hd);
1341 rt->rtsp_hd = rt->rtsp_hd_out = NULL; 1337 rt->rtsp_hd = rt->rtsp_hd_out = NULL;
1342 } 1338 }
1343 1339
1344 int ff_rtsp_connect(AVFormatContext *s) 1340 int ff_rtsp_connect(AVFormatContext *s)
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) { 1537 if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
1542 rt->server_type = RTSP_SERVER_REAL; 1538 rt->server_type = RTSP_SERVER_REAL;
1543 continue; 1539 continue;
1544 } else if (!strncasecmp(reply->server, "WMServer/", 9)) { 1540 } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
1545 rt->server_type = RTSP_SERVER_WMS; 1541 rt->server_type = RTSP_SERVER_WMS;
1546 } else if (rt->server_type == RTSP_SERVER_REAL) 1542 } else if (rt->server_type == RTSP_SERVER_REAL)
1547 strcpy(real_challenge, reply->real_challenge); 1543 strcpy(real_challenge, reply->real_challenge);
1548 break; 1544 break;
1549 } 1545 }
1550 1546
1551 if (s->iformat) 1547 if (s->iformat && CONFIG_RTSP_DEMUXER)
1552 err = rtsp_setup_input_streams(s, reply); 1548 err = rtsp_setup_input_streams(s, reply);
1553 else 1549 else if (CONFIG_RTSP_MUXER)
1554 err = rtsp_setup_output_streams(s, host); 1550 err = rtsp_setup_output_streams(s, host);
1555 if (err) 1551 if (err)
1556 goto fail; 1552 goto fail;
1557 1553
1558 do { 1554 do {
1559 int lower_transport = ff_log2_tab[lower_transport_mask & 1555 int lower_transport = ff_log2_tab[lower_transport_mask &
1560 ~(lower_transport_mask - 1)]; 1556 ~(lower_transport_mask - 1)];
1561 1557
1562 err = make_setup_request(s, host, port, lower_transport, 1558 err = make_setup_request(s, host, port, lower_transport,
1563 rt->server_type == RTSP_SERVER_REAL ? 1559 rt->server_type == RTSP_SERVER_REAL ?
(...skipping 18 matching lines...) Expand all
1582 av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n", 1578 av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
1583 reply->status_code, 1579 reply->status_code,
1584 s->filename); 1580 s->filename);
1585 goto redirect; 1581 goto redirect;
1586 } 1582 }
1587 ff_network_close(); 1583 ff_network_close();
1588 return err; 1584 return err;
1589 } 1585 }
1590 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */ 1586 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
1591 1587
1588 #if CONFIG_RTPDEC
1592 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, 1589 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1593 uint8_t *buf, int buf_size, int64_t wait_end) 1590 uint8_t *buf, int buf_size, int64_t wait_end)
1594 { 1591 {
1595 RTSPState *rt = s->priv_data; 1592 RTSPState *rt = s->priv_data;
1596 RTSPStream *rtsp_st; 1593 RTSPStream *rtsp_st;
1597 fd_set rfds; 1594 fd_set rfds;
1598 int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0; 1595 int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
1599 struct timeval tv; 1596 struct timeval tv;
1600 1597
1601 for (;;) { 1598 for (;;) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 } 1767 }
1771 end: 1768 end:
1772 if (ret < 0) 1769 if (ret < 0)
1773 goto redo; 1770 goto redo;
1774 if (ret == 1) 1771 if (ret == 1)
1775 /* more packets may follow, so we save the RTP context */ 1772 /* more packets may follow, so we save the RTP context */
1776 rt->cur_transport_priv = rtsp_st->transport_priv; 1773 rt->cur_transport_priv = rtsp_st->transport_priv;
1777 1774
1778 return ret; 1775 return ret;
1779 } 1776 }
1777 #endif /* CONFIG_RTPDEC */
1780 1778
1781 #if CONFIG_RTSP_DEMUXER 1779 #if CONFIG_RTSP_DEMUXER
1780 static int rtsp_probe(AVProbeData *p)
1781 {
1782 if (av_strstart(p->filename, "rtsp:", NULL))
1783 return AVPROBE_SCORE_MAX;
1784 return 0;
1785 }
1786
1782 static int rtsp_read_header(AVFormatContext *s, 1787 static int rtsp_read_header(AVFormatContext *s,
1783 AVFormatParameters *ap) 1788 AVFormatParameters *ap)
1784 { 1789 {
1785 RTSPState *rt = s->priv_data; 1790 RTSPState *rt = s->priv_data;
1786 int ret; 1791 int ret;
1787 1792
1788 ret = ff_rtsp_connect(s); 1793 ret = ff_rtsp_connect(s);
1789 if (ret) 1794 if (ret)
1790 return ret; 1795 return ret;
1791 1796
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 rtsp_read_header, 2018 rtsp_read_header,
2014 rtsp_read_packet, 2019 rtsp_read_packet,
2015 rtsp_read_close, 2020 rtsp_read_close,
2016 rtsp_read_seek, 2021 rtsp_read_seek,
2017 .flags = AVFMT_NOFILE, 2022 .flags = AVFMT_NOFILE,
2018 .read_play = rtsp_read_play, 2023 .read_play = rtsp_read_play,
2019 .read_pause = rtsp_read_pause, 2024 .read_pause = rtsp_read_pause,
2020 }; 2025 };
2021 #endif /* CONFIG_RTSP_DEMUXER */ 2026 #endif /* CONFIG_RTSP_DEMUXER */
2022 2027
2028 #if CONFIG_SDP_DEMUXER
2023 static int sdp_probe(AVProbeData *p1) 2029 static int sdp_probe(AVProbeData *p1)
2024 { 2030 {
2025 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; 2031 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2026 2032
2027 /* we look for a line beginning "c=IN IP" */ 2033 /* we look for a line beginning "c=IN IP" */
2028 while (p < p_end && *p != '\0') { 2034 while (p < p_end && *p != '\0') {
2029 if (p + sizeof("c=IN IP") - 1 < p_end && 2035 if (p + sizeof("c=IN IP") - 1 < p_end &&
2030 av_strstart(p, "c=IN IP", NULL)) 2036 av_strstart(p, "c=IN IP", NULL))
2031 return AVPROBE_SCORE_MAX / 2; 2037 return AVPROBE_SCORE_MAX / 2;
2032 2038
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2097 2103
2098 AVInputFormat sdp_demuxer = { 2104 AVInputFormat sdp_demuxer = {
2099 "sdp", 2105 "sdp",
2100 NULL_IF_CONFIG_SMALL("SDP"), 2106 NULL_IF_CONFIG_SMALL("SDP"),
2101 sizeof(RTSPState), 2107 sizeof(RTSPState),
2102 sdp_probe, 2108 sdp_probe,
2103 sdp_read_header, 2109 sdp_read_header,
2104 rtsp_fetch_packet, 2110 rtsp_fetch_packet,
2105 sdp_read_close, 2111 sdp_read_close,
2106 }; 2112 };
2113 #endif /* CONFIG_SDP_DEMUXER */
2114
2115 #if CONFIG_RTP_DEMUXER
2116 static int rtp_probe(AVProbeData *p)
2117 {
2118 if (av_strstart(p->filename, "rtp:", NULL))
2119 return AVPROBE_SCORE_MAX;
2120 return 0;
2121 }
2122
2123 static int rtp_read_header(AVFormatContext *s,
2124 AVFormatParameters *ap)
2125 {
2126 uint8_t recvbuf[1500];
2127 char host[500], sdp[500];
2128 int ret, port;
2129 URLContext* in = NULL;
2130 int payload_type;
2131 AVCodecContext codec;
2132 struct sockaddr_storage addr;
2133 ByteIOContext pb;
2134 socklen_t addrlen = sizeof(addr);
2135
2136 if (!ff_network_init())
2137 return AVERROR(EIO);
2138
2139 ret = url_open(&in, s->filename, URL_RDONLY);
2140 if (ret)
2141 goto fail;
2142
2143 while (1) {
2144 ret = url_read(in, recvbuf, sizeof(recvbuf));
2145 if (ret == AVERROR(EAGAIN))
2146 continue;
2147 if (ret < 0)
2148 goto fail;
2149 if (ret < 12) {
2150 av_log(s, AV_LOG_WARNING, "Received too short packet\n");
2151 continue;
2152 }
2153
2154 if ((recvbuf[0] & 0xc0) != 0x80) {
2155 av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
2156 "received\n");
2157 continue;
2158 }
2159
2160 payload_type = recvbuf[1] & 0x7f;
2161 break;
2162 }
2163 getsockname(url_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
2164 url_close(in);
2165 in = NULL;
2166
2167 memset(&codec, 0, sizeof(codec));
2168 if (ff_rtp_get_codec_info(&codec, payload_type)) {
2169 av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
2170 "without an SDP file describing it\n",
2171 payload_type);
2172 goto fail;
2173 }
2174 if (codec.codec_type != AVMEDIA_TYPE_DATA) {
2175 av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
2176 "properly you need an SDP file "
2177 "describing it\n");
2178 }
2179
2180 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
2181 NULL, 0, s->filename);
2182
2183 snprintf(sdp, sizeof(sdp),
2184 "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
2185 addr.ss_family == AF_INET ? 4 : 6, host,
2186 codec.codec_type == AVMEDIA_TYPE_DATA ? "application" :
2187 codec.codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
2188 port, payload_type);
2189 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
2190
2191 init_put_byte(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
2192 s->pb = &pb;
2193
2194 /* sdp_read_header initializes this again */
2195 ff_network_close();
2196
2197 ret = sdp_read_header(s, ap);
2198 s->pb = NULL;
2199 return ret;
2200
2201 fail:
2202 if (in)
2203 url_close(in);
2204 ff_network_close();
2205 return ret;
2206 }
2207
2208 AVInputFormat rtp_demuxer = {
2209 "rtp",
2210 NULL_IF_CONFIG_SMALL("RTP input format"),
2211 sizeof(RTSPState),
2212 rtp_probe,
2213 rtp_read_header,
2214 rtsp_fetch_packet,
2215 sdp_read_close,
2216 .flags = AVFMT_NOFILE,
2217 };
2218 #endif /* CONFIG_RTP_DEMUXER */
2219
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698