Index: libmpdemux/realrtsp/real.c =================================================================== --- libmpdemux/realrtsp/real.c (révision 18722) +++ libmpdemux/realrtsp/real.c (copie de travail) @@ -800,7 +800,7 @@ rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=0", mrl); - rtsp_request_setup(rtsp_session,buf); + rtsp_request_setup(rtsp_session,buf,NULL); if (h->prop->num_streams > 1) { rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); @@ -810,7 +810,7 @@ buf = xbuffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=1", mrl); - rtsp_request_setup(rtsp_session,buf); + rtsp_request_setup(rtsp_session,buf,NULL); } /* set stream parameter (bandwidth) with our subscribe string */ rtsp_schedule_field(rtsp_session, subscribe); Index: libmpdemux/realrtsp/rtsp.c =================================================================== --- libmpdemux/realrtsp/rtsp.c (révision 18722) +++ libmpdemux/realrtsp/rtsp.c (copie de travail) @@ -24,6 +24,9 @@ * * a minimalistic implementation of rtsp protocol, * *not* RFC 2326 compilant yet. + * + * 2006, Benjamin Zores and Vincent Mussard + * fixed a lot of RFC compliance issues. */ #include @@ -89,7 +92,7 @@ * constants */ -const char rtsp_protocol_version[]="RTSP/1.0"; +#define RTSP_PROTOCOL_VERSION "RTSP/1.0" /* server states */ #define RTSP_CONNECTED 1 @@ -197,7 +200,7 @@ total = 0; - while (total < count) { + while (total < (ssize_t) count) { ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); @@ -336,12 +339,12 @@ char buf[4]; int code=0; - if (!strncmp(string, rtsp_protocol_version, strlen(rtsp_protocol_version))) + if (!strncmp(string, RTSP_PROTOCOL_VERSION, strlen(RTSP_PROTOCOL_VERSION))) { - memcpy(buf, string+strlen(rtsp_protocol_version)+1, 3); + memcpy(buf, string+strlen(RTSP_PROTOCOL_VERSION)+1, 3); buf[3]=0; code=atoi(buf); - } else if (!strncmp(string, "SET_PARAMETER",8)) + } else if (!strncmp(string, RTSP_METHOD_SET_PARAMETER,8)) { return RTSP_STATUS_SET_PARAMETER; } @@ -360,9 +363,9 @@ char **payload=s->scheduled; char *buf; - buf = malloc(strlen(type)+strlen(what)+strlen(rtsp_protocol_version)+3); + buf = malloc(strlen(type)+strlen(what)+strlen(RTSP_PROTOCOL_VERSION)+3); - sprintf(buf,"%s %s %s",type, what, rtsp_protocol_version); + sprintf(buf,"%s %s %s",type, what, RTSP_PROTOCOL_VERSION); rtsp_put(s,buf); free(buf); if (payload) @@ -382,7 +385,7 @@ char tmp[16]; - snprintf(tmp, 16, "Cseq: %u", s->cseq); + snprintf(tmp, 16, "CSeq: %u", s->cseq); rtsp_schedule_field(s, tmp); if (s->session) { @@ -419,11 +422,11 @@ if (!answer) return 0; - if (!strncmp(answer,"Cseq:",5)) { - sscanf(answer,"Cseq: %u",&answer_seq); + if (!strncmp(answer,"CSeq:",5)) { + sscanf(answer,"CSeq: %u",&answer_seq); if (s->cseq != answer_seq) { #ifdef LOG - mp_msg(MSGT_OPEN, MSGL_WARN, "librtsp: warning: Cseq mismatch. got %u, assumed %u", answer_seq, s->cseq); + mp_msg(MSGT_OPEN, MSGL_WARN, "librtsp: warning: CSeq mismatch. got %u, assumed %u", answer_seq, s->cseq); #endif s->cseq=answer_seq; } @@ -495,7 +498,7 @@ buf=malloc(sizeof(char)*(strlen(s->host)+16)); sprintf(buf,"rtsp://%s:%i", s->host, s->port); } - rtsp_send_request(s,"OPTIONS",buf); + rtsp_send_request(s,RTSP_METHOD_OPTIONS,buf); free(buf); return rtsp_get_answers(s); @@ -512,17 +515,32 @@ buf=malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16)); sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); } - rtsp_send_request(s,"DESCRIBE",buf); + rtsp_send_request(s,RTSP_METHOD_DESCRIBE,buf); free(buf); return rtsp_get_answers(s); } -int rtsp_request_setup(rtsp_t *s, const char *what) { +int rtsp_request_setup(rtsp_t *s, const char *what, char *control) { - rtsp_send_request(s,"SETUP",what); + char *buf = NULL; + + if (what) + buf = strdup (what); + else + { + int len = strlen (s->host) + strlen (s->path) + 16; + if (control) + len += strlen (control) + 1; + + buf = malloc (len * sizeof (char)); + sprintf (buf, "rtsp://%s:%i/%s%s%s", s->host, s->port, s->path, + control ? "/" : "", control ? control : ""); + } - return rtsp_get_answers(s); + rtsp_send_request (s, RTSP_METHOD_SETUP, buf); + free (buf); + return rtsp_get_answers (s); } int rtsp_request_setparameter(rtsp_t *s, const char *what) { @@ -536,7 +554,7 @@ buf=malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16)); sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); } - rtsp_send_request(s,"SET_PARAMETER",buf); + rtsp_send_request(s,RTSP_METHOD_SET_PARAMETER,buf); free(buf); return rtsp_get_answers(s); @@ -545,7 +563,8 @@ int rtsp_request_play(rtsp_t *s, const char *what) { char *buf; - + int ret; + if (what) { buf=strdup(what); } else @@ -553,16 +572,32 @@ buf=malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16)); sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path); } - rtsp_send_request(s,"PLAY",buf); + + rtsp_send_request(s,RTSP_METHOD_PLAY,buf); free(buf); - - return rtsp_get_answers(s); + + ret = rtsp_get_answers (s); + if (ret == 200) + s->server_state = RTSP_PLAYING; + + return ret; } -int rtsp_request_tearoff(rtsp_t *s, const char *what) { +int rtsp_request_teardown(rtsp_t *s, const char *what) { - rtsp_send_request(s,"TEAROFF",what); - + char *buf; + + if (what) + buf = strdup (what); + else + { + buf = + malloc (sizeof (char) * (strlen (s->host) + strlen (s->path) + 16)); + sprintf (buf, "rtsp://%s:%i/%s", s->host, s->port, s->path); + } + rtsp_send_request (s, RTSP_METHOD_TEARDOWN, buf); + free (buf); + return rtsp_get_answers(s); } @@ -596,7 +631,7 @@ free(rest); if (seq<0) { #ifdef LOG - mp_msg(MSGT_OPEN, MSGL_WARN, "rtsp: warning: cseq not recognized!\n"); + mp_msg(MSGT_OPEN, MSGL_WARN, "rtsp: warning: CSeq not recognized!\n"); #endif seq=1; } @@ -640,7 +675,7 @@ s->server_state=0; s->server_caps=0; - s->cseq=1; + s->cseq=0; s->session=NULL; if (user_agent) @@ -690,7 +725,13 @@ void rtsp_close(rtsp_t *s) { - if (s->server_state) closesocket(s->s); /* TODO: send a TEAROFF */ + if (s->server_state) + { + if (s->server_state == RTSP_PLAYING) + rtsp_request_teardown (s, NULL); + closesocket (s->s); + } + if (s->path) free(s->path); if (s->host) free(s->host); if (s->mrl) free(s->mrl); @@ -752,6 +793,11 @@ } +char *rtsp_get_host (rtsp_t * s) +{ + return s->host; +} + char *rtsp_get_param(rtsp_t *s, char *p) { int len; char *param; @@ -805,6 +851,8 @@ while(*ptr) { if (!strncmp(*ptr, string, strlen(string))) break; + else + ptr++; } if (*ptr) free(*ptr); ptr++; Index: libmpdemux/realrtsp/rtsp.h =================================================================== --- libmpdemux/realrtsp/rtsp.h (révision 18722) +++ libmpdemux/realrtsp/rtsp.h (copie de travail) @@ -24,6 +24,9 @@ * * a minimalistic implementation of rtsp protocol, * *not* RFC 2326 compilant yet. + * + * 2006, Benjamin Zores and Vincent Mussard + * fixed a lot of RFC compliance issues. */ #ifndef HAVE_RTSP_H @@ -35,16 +38,23 @@ #define RTSP_STATUS_SET_PARAMETER 10 #define RTSP_STATUS_OK 200 +#define RTSP_METHOD_OPTIONS "OPTIONS" +#define RTSP_METHOD_DESCRIBE "DESCRIBE" +#define RTSP_METHOD_SETUP "SETUP" +#define RTSP_METHOD_PLAY "PLAY" +#define RTSP_METHOD_TEARDOWN "TEARDOWN" +#define RTSP_METHOD_SET_PARAMETER "SET_PARAMETER" + typedef struct rtsp_s rtsp_t; rtsp_t* rtsp_connect (int fd, char *mrl, char *path, char *host, int port, char *user_agent); int rtsp_request_options(rtsp_t *s, const char *what); int rtsp_request_describe(rtsp_t *s, const char *what); -int rtsp_request_setup(rtsp_t *s, const char *what); +int rtsp_request_setup(rtsp_t *s, const char *what, char *control); int rtsp_request_setparameter(rtsp_t *s, const char *what); int rtsp_request_play(rtsp_t *s, const char *what); -int rtsp_request_tearoff(rtsp_t *s, const char *what); +int rtsp_request_teardown(rtsp_t *s, const char *what); int rtsp_send_ok(rtsp_t *s); @@ -62,6 +72,7 @@ char *rtsp_get_session(rtsp_t *s); char *rtsp_get_mrl(rtsp_t *s); +char *rtsp_get_host(rtsp_t *s); char *rtsp_get_param(rtsp_t *s, char *param); /*int rtsp_peek_header (rtsp_t *this, char *data); */