📄 real.c
字号:
if(ret < 0) { goto failed; } *rtsp_hdr_ret = rtsp_hdr; if(options_uri) free(options_uri); return ret; failed: if(rtsp_hdr) free_rtsp_header(rtsp_hdr); if(options_uri) free(options_uri); *rtsp_hdr_ret = NULL; return -1;}/* * send DESCRIBE request * return value: -1: failure status_code: success */static int real_rtsp_describe(struct stream_t *stream,char **description_ret){ struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl; struct rtsp_ctrl_t *rtsp_ctrl = stream_ctrl->rtsp_ctrl; struct rtsp_header_t *rtsp_hdr = NULL; char *description = NULL; char *buffer = xmalloc(BUFSIZE_1K); char *field = NULL; int len = 0; int ret = 0; rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl); rtsp_set_field(rtsp_hdr, "Accept: application/sdp"); rtsp_set_field(rtsp_hdr, real_useragent); rtsp_set_field(rtsp_hdr, "Require: com.real.retain-entity-for-setup"); snprintf(buffer,BUFSIZE_1K - 1,"Bandwidth: %u",stream_ctrl->bandwidth); rtsp_set_field(rtsp_hdr,buffer); rtsp_set_field(rtsp_hdr, "Language: en-US"); rtsp_set_field(rtsp_hdr, "RegionData: 0"); rtsp_set_field(rtsp_hdr, real_clientid); rtsp_set_field(rtsp_hdr, "GUID: 00000000-0000-0000-0000-000000000000"); rtsp_set_field(rtsp_hdr, "SupportsMaximumASMBandwidth: 1"); rtsp_request_describe(rtsp_hdr,rtsp_ctrl->mrl); rtsp_send_request_and_free(stream,rtsp_hdr); rtsp_hdr = new_rtsp_header(); ret = rtsp_recv_header(stream,rtsp_hdr); if(ret < 0) { free_rtsp_header(rtsp_hdr); goto failed; } /* NOT OK */ if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { display(MSDL_ERR,"DESCRIBE request returned: %d (%s)\n", rtsp_hdr->status_code,rtsp_hdr->reason_phrase); field = rtsp_get_field(rtsp_hdr,"Alert"); if(field) { while(*field == ' ') field++; display(MSDL_ERR,"message from server --> %s\n",field); } free_rtsp_header(rtsp_hdr); goto failed; } len = 0; /* Content-length must be present */ if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) { while(*field == ' ') field++; len = atoi(field); } else { /* no Content-length */ display(MSDL_ERR,"warning: No Content-length in fields!!\n"); } if((field = rtsp_get_field(rtsp_hdr,"ETag")) != NULL) { while(*field == ' ') field++; rtsp_ctrl->etag = strdup(field); } else { display(MSDL_ERR,"warning: No ETag!!\n"); rtsp_ctrl->etag = NULL; } free_rtsp_header(rtsp_hdr); /* copy description (sdp) */ description = (char *)xmalloc(len + 1); read_data(stream,(uint8_t *)description,len); description[len] = '\0'; display(MSDL_DBG,"==================\n%s\n=(%d bytes)========\n", description,(int)strlen(description)); if(buffer) free(buffer); *description_ret = description; return ret; failed: if(description) free(description); if(buffer) free(buffer); *description_ret = NULL; return -1;}/* * send SETUP requst. 2 setups for multiple streams. * return value ... what rtsp_recv_header returned */static int real_rtsp_setup(struct stream_t *stream,struct rmff_header_t *rmff_header){ struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl; struct rtsp_header_t *rtsp_hdr = NULL; char *buffer = xmalloc(BUFSIZE_1K); int ret = 0; char challenge2[64]; char checksum[34]; rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl); real_calc_challenge2_and_checksum(rtsp_ctrl->challenge,challenge2,checksum); snprintf(buffer,BUFSIZE_1K - 1,"RealChallenge2: %s, sd=%s", challenge2,checksum); rtsp_set_field(rtsp_hdr,buffer); snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag); rtsp_set_field(rtsp_hdr,buffer); rtsp_set_field(rtsp_hdr,"RDTFeatureLevel: 2"); rtsp_set_field(rtsp_hdr,real_transport); snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=0",rtsp_ctrl->mrl); rtsp_request_setup(rtsp_hdr,buffer); rtsp_send_request_and_free(stream,rtsp_hdr); /* receive message for SETUP */ ret = rtsp_recv_header_ignore_message(stream); /* send messages if multiple stream exists (max is 2 streams anyways...) */ if(rmff_header->prop->num_streams > 1) { rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl); rtsp_set_field(rtsp_hdr,real_transport); snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag); rtsp_set_field(rtsp_hdr,buffer); snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=1",rtsp_ctrl->mrl); rtsp_request_setup(rtsp_hdr,buffer); rtsp_send_request_and_free(stream,rtsp_hdr); /* receive message for SETUP */ ret = rtsp_recv_header_ignore_message(stream); } free(buffer); return ret; }/* * send SET_PARAMETER, with stream choosing subscribe. * return value ... what rtsp_recv_header returned */static int real_rtsp_set_parameter(struct stream_t *stream,char *subscribe){ struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl; struct rtsp_header_t *rtsp_hdr = NULL; int ret = 0; rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl); rtsp_set_field(rtsp_hdr,subscribe); if(stream->dlopts->bandwidth) { /* when user specified bandwidth */ char *buffer = xmalloc(BUFSIZE_1K); snprintf(buffer,BUFSIZE_1K - 1, "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth); rtsp_set_field(rtsp_hdr,buffer); free(buffer); } rtsp_request_set_parameter(rtsp_hdr,rtsp_ctrl->mrl); rtsp_send_request_and_free(stream,rtsp_hdr); ret = rtsp_recv_header_ignore_message(stream); return ret;}/* * send PLAY request * return value ... what rtsp_recv_header returned */static int real_rtsp_play(struct stream_t *stream){ struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl; struct rtsp_header_t *rtsp_hdr = NULL; char *field = NULL; int ret = 0; /* * Sending part */ rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl); if(stream->dlopts->resume_download) { real_prepare_resuming(stream); } if(stream->dlopts->bandwidth) { /* when user specified bandwidth */ char *buffer = xmalloc(BUFSIZE_1K); snprintf(buffer,BUFSIZE_1K - 1, "Bandwidth: %d",stream->dlopts->bandwidth); rtsp_set_field(rtsp_hdr,buffer); free(buffer); } rtsp_set_range_field(rtsp_hdr,stream->dlopts->range); rtsp_set_speed_field(rtsp_hdr,stream->dlopts->speed); rtsp_request_play(rtsp_hdr,rtsp_ctrl->mrl); rtsp_send_request_and_free(stream,rtsp_hdr); /* * Receiving part */ /* receive message for PLAY request */ rtsp_hdr = new_rtsp_header(); ret = rtsp_recv_header(stream,rtsp_hdr); if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { display(MSDL_ERR,"PLAY request returned: %d (%s)\n", rtsp_hdr->status_code,rtsp_hdr->reason_phrase); field = rtsp_get_field(rtsp_hdr,"Alert"); if(field) { while(*field == ' ') field++; display(MSDL_ERR,"message from server --> %s\n",field); } free_rtsp_header(rtsp_hdr); goto failed; } /* display real speed (might differ from user requested) */ if((field = rtsp_get_field(rtsp_hdr,"Speed")) != NULL) { if(stream->dlopts->speed) { while(*field == ' ') field++; display(MSDL_NOR,"Speed: %s\n",field); } } if((field = rtsp_get_field(rtsp_hdr,"Range")) != NULL) { if(stream->dlopts->range) { while(*field == ' ') field++; display(MSDL_NOR,"Range: %s\n",field); } } /* skip content-length bytes from network */ rtsp_ignore_data_after_header(stream,rtsp_hdr); free_rtsp_header(rtsp_hdr); return ret; failed: return -1;}/* * send SETUP,SEND_REQUEST,PLAY requests. * * return value 1: success * -1: error */int real_setup_and_get_header(struct stream_t *stream, struct rmff_header_t **rmff_header_ret){ struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl; struct rmff_header_t *rmff_header = NULL; char *description = NULL; char *subscribe = NULL; /* !!!CAUTION!!! setting maxbw too high may cause download failure!! */ /* don't use this value, its just for choosing highest rate stream */ if(stream->dlopts->bandwidth) { stream_ctrl->bandwidth = stream->dlopts->bandwidth; } else { stream_ctrl->bandwidth = 10485800; } if(real_rtsp_describe(stream,&description) < 0) { goto failed; } /* parse sdp and get information about file to download */ rmff_header = real_parse_sdp(description,&subscribe,stream_ctrl->bandwidth); if(!rmff_header) { goto failed; } display(MSDL_VER,"sdp parse done.\n"); /* send SETUP request */ if(real_rtsp_setup(stream,rmff_header) < 0) { goto failed; } /* send SET_PARAMETER request to download stream */ if(real_rtsp_set_parameter(stream,subscribe) < 0) { goto failed; } /* send PLAY request to download stream */ if(real_rtsp_play(stream) < 0) { goto failed; } free(subscribe); free(description); *rmff_header_ret = rmff_header; return 1; failed: if(subscribe) free(subscribe); if(description) free(description); if(rmff_header) free_rmff_header_t(rmff_header); *rmff_header_ret = NULL; return -1;}/* * read from media stream. (real rdp packet) * * fill 'buffer' with data, and buffer size is 'max_size'. * receive one chunk from netsock->sock, and fills 'max_size' bytes to buffer. * and if there are more bytes in the chunk, the data is stored to * stream->netsock->buffer. * * return value: positive value ... bytes written to buffer. * 0 ... END OF STREAM * -1 ... ERROR */int real_rdt_get_media_packet(struct stream_t *stream, uint8_t *buffer,size_t max_size){ int ret = 0; uint8_t header[8]; ret = read_data(stream,header,8); if(ret < 0) { goto failed; } while(!strncasecmp((char *)header,"SET_",4) || !strncasecmp((char *)header,"GET_",4) || !strncasecmp((char *)header,"OPTI",4) || !strncasecmp((char *)header,"RTSP",4) || !strncasecmp((char *)header,"ANNO",4)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -