comparison rtsp.c @ 304:d58c8859ff8c libavformat

initial seek support - more generic play/pause support
author bellard
date Mon, 10 Nov 2003 18:39:26 +0000
parents 6091b76cfc2a
children 845f9de2c883
comparison
equal deleted inserted replaced
303:2833c2311b66 304:d58c8859ff8c
29 #endif 29 #endif
30 30
31 //#define DEBUG 31 //#define DEBUG
32 //#define DEBUG_RTP_TCP 32 //#define DEBUG_RTP_TCP
33 33
34 enum RTSPClientState {
35 RTSP_STATE_IDLE,
36 RTSP_STATE_PLAYING,
37 RTSP_STATE_PAUSED,
38 };
39
34 typedef struct RTSPState { 40 typedef struct RTSPState {
35 URLContext *rtsp_hd; /* RTSP TCP connexion handle */ 41 URLContext *rtsp_hd; /* RTSP TCP connexion handle */
36 int nb_rtsp_streams; 42 int nb_rtsp_streams;
37 struct RTSPStream **rtsp_streams; 43 struct RTSPStream **rtsp_streams;
38 44
45 enum RTSPClientState state;
46 int64_t seek_timestamp;
47
39 /* XXX: currently we use unbuffered input */ 48 /* XXX: currently we use unbuffered input */
40 // ByteIOContext rtsp_gb; 49 // ByteIOContext rtsp_gb;
41 int seq; /* RTSP command sequence number */ 50 int seq; /* RTSP command sequence number */
42 char session_id[512]; 51 char session_id[512];
43 enum RTSPProtocol protocol; 52 enum RTSPProtocol protocol;
57 struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */ 66 struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */
58 int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */ 67 int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */
59 int sdp_payload_type; /* payload type - only used in SDP */ 68 int sdp_payload_type; /* payload type - only used in SDP */
60 } RTSPStream; 69 } RTSPStream;
61 70
71 static int rtsp_read_play(AVFormatContext *s);
72
62 /* XXX: currently, the only way to change the protocols consists in 73 /* XXX: currently, the only way to change the protocols consists in
63 changing this variable */ 74 changing this variable */
64 #if 1 75 #if 0
65 int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST); 76 int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST);
66 #else 77 #else
67 /* try it if a proxy is used */ 78 /* try it if a proxy is used */
68 int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP); 79 int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
69 #endif 80 #endif
510 521
511 reply->nb_transports++; 522 reply->nb_transports++;
512 } 523 }
513 } 524 }
514 525
526 static void rtsp_parse_range_npt(RTSPHeader *reply, const char *p)
527 {
528 char buf[256];
529
530 skip_spaces(&p);
531 if (!stristart(p, "npt=", &p))
532 return;
533
534 reply->range_start = AV_NOPTS_VALUE;
535 reply->range_end = AV_NOPTS_VALUE;
536
537 get_word_sep(buf, sizeof(buf), "-", &p);
538 reply->range_start = parse_date(buf, 1);
539 if (*p == '-') {
540 p++;
541 get_word_sep(buf, sizeof(buf), "-", &p);
542 reply->range_end = parse_date(buf, 1);
543 }
544 }
545
515 void rtsp_parse_line(RTSPHeader *reply, const char *buf) 546 void rtsp_parse_line(RTSPHeader *reply, const char *buf)
516 { 547 {
517 const char *p; 548 const char *p;
518 549
519 /* NOTE: we do case independent match for broken servers */ 550 /* NOTE: we do case independent match for broken servers */
524 reply->content_length = strtol(p, NULL, 10); 555 reply->content_length = strtol(p, NULL, 10);
525 } else if (stristart(p, "Transport:", &p)) { 556 } else if (stristart(p, "Transport:", &p)) {
526 rtsp_parse_transport(reply, p); 557 rtsp_parse_transport(reply, p);
527 } else if (stristart(p, "CSeq:", &p)) { 558 } else if (stristart(p, "CSeq:", &p)) {
528 reply->seq = strtol(p, NULL, 10); 559 reply->seq = strtol(p, NULL, 10);
560 } else if (stristart(p, "Range:", &p)) {
561 rtsp_parse_range_npt(reply, p);
529 } 562 }
530 } 563 }
531 564
532 /* skip a RTP/TCP interleaved packet */ 565 /* skip a RTP/TCP interleaved packet */
533 static void rtsp_skip_packet(AVFormatContext *s) 566 static void rtsp_skip_packet(AVFormatContext *s)
854 err = AVERROR_INVALIDDATA; 887 err = AVERROR_INVALIDDATA;
855 goto fail; 888 goto fail;
856 } 889 }
857 } 890 }
858 891
859 /* start playing */ 892
860 snprintf(cmd, sizeof(cmd), 893 rt->state = RTSP_STATE_IDLE;
861 "PLAY %s RTSP/1.0\r\n" 894 rt->seek_timestamp = 0; /* default is to start stream at position
862 "Range: npt=0-\r\n", 895 zero */
863 s->filename); 896 if (ap && ap->initial_pause) {
864 rtsp_send_cmd(s, cmd, reply, NULL); 897 /* do not start immediately */
865 if (reply->status_code != RTSP_STATUS_OK) { 898 } else {
866 err = AVERROR_INVALIDDATA; 899 if (rtsp_read_play(s) < 0) {
867 goto fail; 900 err = AVERROR_INVALIDDATA;
868 }
869
870 #if 0
871 /* open TCP with bufferized input */
872 if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
873 if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) {
874 err = AVERROR_NOMEM;
875 goto fail; 901 goto fail;
876 } 902 }
877 } 903 }
878 #endif
879
880 return 0; 904 return 0;
881 fail: 905 fail:
882 rtsp_close_streams(rt); 906 rtsp_close_streams(rt);
883 av_freep(&content); 907 av_freep(&content);
884 url_close(rt->rtsp_hd); 908 url_close(rt->rtsp_hd);
1018 rt->cur_rtp = rtsp_st->rtp_ctx; 1042 rt->cur_rtp = rtsp_st->rtp_ctx;
1019 } 1043 }
1020 return 0; 1044 return 0;
1021 } 1045 }
1022 1046
1023 /* pause the stream */ 1047 static int rtsp_read_play(AVFormatContext *s)
1024 int rtsp_pause(AVFormatContext *s) 1048 {
1025 { 1049 RTSPState *rt = s->priv_data;
1026 RTSPState *rt;
1027 RTSPHeader reply1, *reply = &reply1; 1050 RTSPHeader reply1, *reply = &reply1;
1028 char cmd[1024]; 1051 char cmd[1024];
1029 1052
1030 if (s->iformat != &rtsp_demux) 1053 printf("hello state=%d\n", rt->state);
1054
1055 if (rt->state == RTSP_STATE_PAUSED) {
1056 snprintf(cmd, sizeof(cmd),
1057 "PLAY %s RTSP/1.0\r\n",
1058 s->filename);
1059 } else {
1060 snprintf(cmd, sizeof(cmd),
1061 "PLAY %s RTSP/1.0\r\n"
1062 "Range: npt=%0.3f-\r\n",
1063 s->filename,
1064 (double)rt->seek_timestamp / AV_TIME_BASE);
1065 }
1066 rtsp_send_cmd(s, cmd, reply, NULL);
1067 if (reply->status_code != RTSP_STATUS_OK) {
1031 return -1; 1068 return -1;
1032 1069 } else {
1070 rt->state = RTSP_STATE_PLAYING;
1071 return 0;
1072 }
1073 }
1074
1075 /* pause the stream */
1076 static int rtsp_read_pause(AVFormatContext *s)
1077 {
1078 RTSPState *rt = s->priv_data;
1079 RTSPHeader reply1, *reply = &reply1;
1080 char cmd[1024];
1081
1033 rt = s->priv_data; 1082 rt = s->priv_data;
1034 1083
1084 if (rt->state != RTSP_STATE_PLAYING)
1085 return 0;
1086
1035 snprintf(cmd, sizeof(cmd), 1087 snprintf(cmd, sizeof(cmd),
1036 "PAUSE %s RTSP/1.0\r\n", 1088 "PAUSE %s RTSP/1.0\r\n",
1037 s->filename); 1089 s->filename);
1038 rtsp_send_cmd(s, cmd, reply, NULL); 1090 rtsp_send_cmd(s, cmd, reply, NULL);
1039 if (reply->status_code != RTSP_STATUS_OK) { 1091 if (reply->status_code != RTSP_STATUS_OK) {
1040 return -1; 1092 return -1;
1041 } else { 1093 } else {
1094 rt->state = RTSP_STATE_PAUSED;
1042 return 0; 1095 return 0;
1043 } 1096 }
1044 } 1097 }
1045 1098
1046 /* resume the stream */ 1099 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1047 int rtsp_resume(AVFormatContext *s) 1100 int64_t timestamp)
1048 { 1101 {
1049 RTSPState *rt; 1102 RTSPState *rt = s->priv_data;
1050 RTSPHeader reply1, *reply = &reply1;
1051 char cmd[1024];
1052
1053 if (s->iformat != &rtsp_demux)
1054 return -1;
1055 1103
1056 rt = s->priv_data; 1104 rt->seek_timestamp = timestamp;
1057 1105 switch(rt->state) {
1058 snprintf(cmd, sizeof(cmd), 1106 default:
1059 "PLAY %s RTSP/1.0\r\n", 1107 case RTSP_STATE_IDLE:
1060 s->filename); 1108 break;
1061 rtsp_send_cmd(s, cmd, reply, NULL); 1109 case RTSP_STATE_PLAYING:
1062 if (reply->status_code != RTSP_STATUS_OK) { 1110 if (rtsp_read_play(s) != 0)
1063 return -1; 1111 return -1;
1064 } else { 1112 break;
1065 return 0; 1113 case RTSP_STATE_PAUSED:
1066 } 1114 rt->state = RTSP_STATE_IDLE;
1115 break;
1116 }
1117 return 0;
1067 } 1118 }
1068 1119
1069 static int rtsp_read_close(AVFormatContext *s) 1120 static int rtsp_read_close(AVFormatContext *s)
1070 { 1121 {
1071 RTSPState *rt = s->priv_data; 1122 RTSPState *rt = s->priv_data;
1099 sizeof(RTSPState), 1150 sizeof(RTSPState),
1100 rtsp_probe, 1151 rtsp_probe,
1101 rtsp_read_header, 1152 rtsp_read_header,
1102 rtsp_read_packet, 1153 rtsp_read_packet,
1103 rtsp_read_close, 1154 rtsp_read_close,
1155 rtsp_read_seek,
1104 .flags = AVFMT_NOFILE, 1156 .flags = AVFMT_NOFILE,
1157 .read_play = rtsp_read_play,
1158 .read_pause = rtsp_read_pause,
1105 }; 1159 };
1106 1160
1107 static int sdp_probe(AVProbeData *p1) 1161 static int sdp_probe(AVProbeData *p1)
1108 { 1162 {
1109 const char *p; 1163 const char *p;