⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	free_rtsp_ctrl_t(stream->stream_ctrl->rtsp_ctrl);	stream->stream_ctrl->rtsp_ctrl = new_rtsp_ctrl_t();	/* free serverinfo_t */	free_serverinfo_t(stream->serverinfo);	stream->serverinfo = new_serverinfo_t();		/* DO NOT MESS WITH	 * stream_t->netsock,	 * stream_t->url,	 * stream_t->dlopts,	 * stream_t->resumeinfo,	 * these are still valid (or just nothing (resumeinfo))	 */	/* re-establish rtsp connection for WMServer */	stream->netsock->sock = rtsp_connect(stream);	if(stream->netsock->sock < 0) {	    /*	      couldn't connect for some reason.	      (rtsp port probably closed)	     */	    display(MSDL_ERR,"rtsp-wms connection not established\n");	    display(MSDL_ERR,"server probably does not accept rtsp\n"		    "retry using mmst protocol\n",server);	    stream->stream_ctrl->status = STREAMING_OTHER_PROTOCOL;	    stream->stream_ctrl->retry_protocol = MMST;	    	    goto failed;	}    	ret = wmserver_setup_and_get_header(stream,&asf_headerinfo);	if(ret == 0) { /* retry    */	    /* probably non-wmserver */	    display(MSDL_ERR,"server probably does not accept rtsp\n"		    "retry using mmst protocol\n",server);	    stream->stream_ctrl->status = STREAMING_OTHER_PROTOCOL;	    stream->stream_ctrl->retry_protocol = MMST;	    	    	    goto failed;	}	else if((!asf_headerinfo) || (ret < 0)) {       /* no retry */	    display(MSDL_ERR,"rtsp setup failed\n");	    goto failed;	}		/* All Green */	stream->stream_ctrl->rtsp_ctrl->asf_headerinfo = asf_headerinfo;    /* set infomation */	stream->stream_ctrl->packet_length = asf_headerinfo->fileh->max_packet_size;	stream->stream_ctrl->file_size = asf_headerinfo->fileh->file_size;	stream->stream_ctrl->total_packets = asf_headerinfo->fileh->num_packets;	stream->stream_ctrl->rtsp_ctrl->get_media_packet = wmserver_rtp_get_media_packet;	/* distinguish which rtsp */	stream->stream_ctrl->rtsp_ctrl->rtsp_protocol = RTSP_WMS_PROTOCOL;	/* for msdl function to know protocol */	stream->stream_ctrl->protocol = RTSP_WMS;	    }    else { /* unsupported servers */	display(MSDL_ERR,"server type [%s] not supported\n",server);		stream->stream_ctrl->rtsp_ctrl->rtsp_protocol = RTSP_UNKNOWN_PROTOCOL;	goto failed;    }        if(server) free(server);    if(rtsp_answer) free_rtsp_header(rtsp_answer);    if(redirected) free(redirected);      stream->stream_ctrl->status = STREAMING_DOWNLOADING;        return 1; /* success */    failed:    if(server)      free(server);    if(rtsp_answer) free_rtsp_header(rtsp_answer);    if(redirected)  free(redirected);    return -1;}/* * new_rtsp_header : create new RTSP header */struct rtsp_header_t *new_rtsp_header(void){    struct rtsp_header_t *hdr;    hdr = (struct rtsp_header_t *)xmalloc(sizeof(struct rtsp_header_t));    return hdr;}/* * free RTSP header */void free_rtsp_header(struct rtsp_header_t *h){    struct rtsp_field_t *field, *prev;      if(h == NULL) return; // rtsp_hdr is not malloc()ed yet.    if(h->protocol) free(h->protocol);    if(h->method) free(h->method);    if(h->uri) free(h->uri);    if(h->reason_phrase) free(h->reason_phrase);    if(h->field_search) free(h->field_search);    if(h->buffer) free(h->buffer);    field = h->first_field;    for(field = h->first_field; field ; ) {	if(field->field_name)	    free(field->field_name);	prev = field;	field = field->next;	free(prev);    }    free(h);}/* * returns first filed with 'field name'. * rtsp_get_next_field will get next field with 'filed_name' */char *rtsp_get_field(struct rtsp_header_t *rtsp_hdr, const char *field_name){    if(!rtsp_hdr || !field_name) return NULL;      rtsp_hdr->field_search_pos = rtsp_hdr->first_field;    rtsp_hdr->field_search = (char *)xrealloc(rtsp_hdr->field_search,					      strlen(field_name) + 1);    /* copy field name first. */    strcpy(rtsp_hdr->field_search, field_name);    /* get first field value with this field_name. */    return rtsp_get_next_field(rtsp_hdr);}/* * return field string after "rtsp_hdr->field_search". *        NULL if not found. */char *rtsp_get_next_field(struct rtsp_header_t *rtsp_hdr){    char *ptr;    struct rtsp_field_t *field;    if(!rtsp_hdr) return NULL;    field = rtsp_hdr->field_search_pos;      while(field) {	ptr = strstr(field->field_name,":");	if(ptr == NULL) return NULL; // the header is not valid...	if(!strncasecmp(field->field_name,rtsp_hdr->field_search,			ptr - field->field_name)) { // found field!!!!	    ptr++; // skip colon.	    while(*ptr == ' ') ptr++; // skip %20	    rtsp_hdr->field_search_pos = field->next; // points to next field.	    return ptr; // return the string without filed name!!	}	field = field->next;    }    return NULL; // NOT FOUND}/* * rtsp_set_field : make new field and attach it to last_field->next. */void rtsp_set_field(struct rtsp_header_t *rtsp_hdr, const char *field_name){    struct rtsp_field_t *new_field;      if(rtsp_hdr == NULL || field_name == NULL) return;      new_field = xmalloc(sizeof(struct rtsp_field_t));    new_field->next = NULL;    new_field->field_name = xmalloc(strlen(field_name) + 1);    strcpy(new_field->field_name, field_name);      if(rtsp_hdr->last_field == NULL) {	rtsp_hdr->first_field = new_field; // this was first filed!!    }    else {	rtsp_hdr->last_field->next = new_field; // attach to last.    }    rtsp_hdr->last_field = new_field;    rtsp_hdr->field_nb++;}void rtsp_set_uri(struct rtsp_header_t *rtsp_hdr,const char *uri){    if(rtsp_hdr == NULL || uri == NULL) return;    rtsp_hdr->uri = xmalloc(strlen(uri) + 1);    strcpy(rtsp_hdr->uri,uri);}void rtsp_set_method(struct rtsp_header_t *rtsp_hdr, const char *method){    if(rtsp_hdr == NULL || method == NULL) return;    rtsp_hdr->method = xmalloc(strlen(method) + 1);    strcpy(rtsp_hdr->method,method);}/* * wrappers for each request */int rtsp_200ok(struct stream_t *stream,int cseq,char *session){    int ret;    int buflen = 100 + strlen(rtsp_protocol_version) + strlen(session);    char *buf = xmalloc(buflen + 1);      snprintf(buf,buflen,	     "%s 200 OK\r\n"	     "Cseq: %u\r\n"	     "Session: %s\r\n"	     "\r\n",	     rtsp_protocol_version,	     cseq,	     session);      ret = xsend(stream->netsock->sock,buf,strlen(buf));    display(MSDL_DBG,"=send 200 OK============\n%s\n=================\n",buf);      free(buf);    return ret;}/* OPTIONS */char *rtsp_request_options(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"OPTIONS");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* DESCRIBE */char *rtsp_request_describe(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"DESCRIBE");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* SETUP */char *rtsp_request_setup(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"SETUP");    rtsp_set_uri(rtsp_hdr,request_uri);      return (rtsp_build_request(rtsp_hdr));}/* SET_PARAMETER */char *rtsp_request_set_parameter(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"SET_PARAMETER");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* GET_PARAMETER */char *rtsp_request_get_parameter(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"GET_PARAMETER");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* PLAY */char *rtsp_request_play(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"PLAY");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* TEARDOWN */char *rtsp_request_teardown(struct rtsp_header_t *rtsp_hdr,char *request_uri){    rtsp_set_method(rtsp_hdr,"TEARDOWN");    rtsp_set_uri(rtsp_hdr,request_uri);    return (rtsp_build_request(rtsp_hdr));}/* * make complete rtsp_header_t. * firstline is first line, such as OPTIONS, DESCRIBE, etc... (see rtsp) * the request string goes to rtsp_hdr->buffer */char *rtsp_build_request(struct rtsp_header_t *rtsp_hdr){    char *ptr;    int len = 0;    struct rtsp_field_t *field;    if(!rtsp_hdr) return NULL;    if(!rtsp_hdr->method) return NULL;    if(!rtsp_hdr->uri) return NULL;      /*     * culculate the request length.     */    len = strlen(rtsp_hdr->method) + strlen(rtsp_hdr->uri) +	strlen(rtsp_protocol_version) + 2 + 2 ; /* 3 is for spaces between*/      /* fields */    field = rtsp_hdr->first_field;    while(field) {	len += strlen(field->field_name) + 2;	field = field->next;    }    /* CRLF at the end */    len += 2;    /* request body    */    if(rtsp_hdr->body) {	len += rtsp_hdr->body_len;    }      if(rtsp_hdr->buffer) {	free(rtsp_hdr->buffer);	rtsp_hdr->buffer = NULL;    }     if(rtsp_hdr->body_len)	len += rtsp_hdr->body_len;      rtsp_hdr->buffer_len = len;    rtsp_hdr->buffer = xmalloc(len + 1); /* 1 for '\0' */      /*      * build the request     */    ptr = rtsp_hdr->buffer;    ptr += sprintf(ptr,"%s %s %s\r\n",rtsp_hdr->method,rtsp_hdr->uri,		   rtsp_protocol_version);      field = rtsp_hdr->first_field;    /* fields */    while(field != NULL) {	ptr += sprintf(ptr,"%s\r\n",field->field_name);	field = field->next;    }    ptr += sprintf(ptr,"\r\n");      if(rtsp_hdr->body != NULL) {	memcpy(ptr,rtsp_hdr->body,rtsp_hdr->body_len);    }      return rtsp_hdr->buffer;}/* * judges if rtsp_hdr is complete RTSP header, or still needs some parts. *    return value :       0 ... NOT complete *                         1 ... COMPLETE!! */int rtsp_is_entire_header(struct rtsp_header_t *rtsp_hdr){    if(rtsp_hdr == NULL) return 0; /* unlikely, but error */      if(rtsp_hdr->buffer == NULL) return 0;   /* nothing received. */    if(strstr(rtsp_hdr->buffer,"\r\n\r\n") ||       strstr(rtsp_hdr->buffer,"\n\n")) {	return 1;    }      return 0;}static struct rtsp_ctrl_t *new_rtsp_ctrl_t(void){    struct rtsp_ctrl_t *ctrlt = 	(struct rtsp_ctrl_t *)xmalloc(sizeof(struct rtsp_ctrl_t));    /* allocate other protocol controllers in       each protocol initiation functions,       such as rmff_header or asf_headerinfo...    */      ctrlt->prev_ts = -1;    ctrlt->prev_stream_number = -1;    ctrlt->rtsp_protocol = RTSP_UNKNOWN_PROTOCOL; /* off course unknown by default */    return ctrlt;}static void free_rtsp_ctrl_t(struct rtsp_ctrl_t *ctrlt){    if(ctrlt->rtsp_protocol == RTSP_REAL_PROTOCOL) {	if(ctrlt->rmff_header) {	    free_rmff_header_t(ctrlt->rmff_header);	}    }    else if(ctrlt->rtsp_protocol == RTSP_WMS_PROTOCOL) {	if(ctrlt->asf_headerinfo) {	    free_asf_headerinfo_t(ctrlt->asf_headerinfo);	}    }    if(ctrlt->mrl)   free(ctrlt->mrl);    if(ctrlt->server) free(ctrlt->server);    if(ctrlt->session) free(ctrlt->session);    if(ctrlt->etag)     free(ctrlt->etag);    if(ctrlt->challenge) free(ctrlt->challenge);      free(ctrlt);}struct stream_t *rtsp_streaming_init(){    struct stream_t *stream = streaming_init_common();    stream->stream_ctrl->rtsp_ctrl = new_rtsp_ctrl_t();      stream->start = rtsp_streaming_start;    stream->read  = rtsp_streaming_read;    stream->close = rtsp_streaming_close;      return stream;}void rtsp_streaming_close(struct stream_t *stream){    if(stream == NULL) return;        /* TEARDOWN */    if(stream->stream_ctrl->status == STREAMING_DOWNLOADING ||        stream->stream_ctrl->status == STREAMING_FINISHED) {	struct rtsp_header_t *rtsp_hdr;	int ret;	/* send teardown request to make server happier. */	rtsp_hdr = new_rtsp_header_with_standard_fields(stream->stream_ctrl->rtsp_ctrl);	rtsp_request_teardown(rtsp_hdr,stream->stream_ctrl->rtsp_ctrl->mrl);	ret = rtsp_send_request_and_free(stream,rtsp_hdr);    }      if(stream->netsock->sock > 0) { /* valid socket --> close */	close(stream->netsock->sock);    }        free_rtsp_ctrl_t(stream->stream_ctrl->rtsp_ctrl);    streaming_close_common(stream);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -