📄 rtsp.c
字号:
if( what ) { buf = strdup(what); } else { buf = malloc( strlen(rtsp->p_private->host) + strlen(rtsp->p_private->path) + 16 ); sprintf( buf, "rtsp://%s:%i/%s", rtsp->p_private->host, rtsp->p_private->port, rtsp->p_private->path ); } rtsp_send_request( rtsp, "SET_PARAMETER", buf ); free( buf ); return rtsp_get_answers( rtsp );}int rtsp_request_play( rtsp_client_t *rtsp, const char *what ){ char *buf; if( what ) { buf = strdup( what ); } else { buf = malloc( strlen(rtsp->p_private->host) + strlen(rtsp->p_private->path) + 16 ); sprintf( buf, "rtsp://%s:%i/%s", rtsp->p_private->host, rtsp->p_private->port, rtsp->p_private->path ); } rtsp_send_request( rtsp, "PLAY", buf ); free( buf ); return rtsp_get_answers( rtsp );}int rtsp_request_tearoff( rtsp_client_t *rtsp, const char *what ){ rtsp_send_request( rtsp, "TEAROFF", what ); return rtsp_get_answers( rtsp );}/* * read opaque data from stream */int rtsp_read_data( rtsp_client_t *rtsp, uint8_t *buffer, unsigned int size ){ int i, seq; if( size >= 4 ) { i = rtsp->pf_read( rtsp->p_userdata, (uint8_t*)buffer, (unsigned int) 4 ); if( i < 4 ) return i; if( buffer[0]=='S' && buffer[1]=='E' && buffer[2]=='T' && buffer[3]=='_' ) { char *rest = rtsp_get( rtsp ); if( !rest ) return -1; seq = -1; do { free( rest ); rest = rtsp_get( rtsp ); if( !rest ) return -1; if( !strncasecmp( rest, "Cseq:", 5 ) ) sscanf( rest, "%*s %u", &seq ); } while( *rest ); free( rest ); if( seq < 0 ) { //fprintf(stderr, "warning: cseq not recognized!\n"); seq = 1; } /* lets make the server happy */ rtsp_put( rtsp, "RTSP/1.0 451 Parameter Not Understood" ); rest = malloc(17); sprintf( rest,"CSeq: %u", seq ); rtsp_put( rtsp, rest ); rtsp_put( rtsp, "" ); free( rest ); i = rtsp->pf_read( rtsp->p_userdata, (unsigned char*)buffer, size ); } else { i = rtsp->pf_read( rtsp->p_userdata, (unsigned char*)buffer + 4, size - 4 ); i += 4; } } else i = rtsp->pf_read( rtsp->p_userdata, (unsigned char*)buffer, size ); //fprintf( stderr, "<< %d of %d bytes\n", i, size ); return i;}/* * connect to a rtsp server */int rtsp_connect( rtsp_client_t *rtsp, const char *psz_mrl, const char *psz_user_agent ){ rtsp_t *s; char *mrl_ptr; char *slash, *colon; unsigned int hostend, pathbegin, i; if( !psz_mrl ) return -1; s = malloc( sizeof(rtsp_t) ); rtsp->p_private = s; if( !strncmp( psz_mrl, "rtsp://", 7 ) ) psz_mrl += 7; mrl_ptr = strdup( psz_mrl ); for( i=0; i<MAX_FIELDS; i++ ) { s->answers[i]=NULL; s->scheduled[i]=NULL; } s->host = NULL; s->port = 554; /* rtsp standard port */ s->path = NULL; s->mrl = strdup(psz_mrl); s->server = NULL; s->server_state = 0; s->server_caps = 0; s->cseq = 0; s->session = NULL; if( psz_user_agent ) s->user_agent = strdup( psz_user_agent ); else s->user_agent = strdup( "User-Agent: RealMedia Player Version " "6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)" ); slash = strchr( mrl_ptr, '/' ); colon = strchr( mrl_ptr, ':' ); if( !slash ) slash = mrl_ptr + strlen(mrl_ptr) + 1; if( !colon ) colon = slash; if( colon > slash ) colon = slash; pathbegin = slash - mrl_ptr; hostend = colon - mrl_ptr; s->host = malloc(hostend+1); strncpy( s->host, mrl_ptr, hostend ); s->host[hostend] = 0; if( pathbegin < strlen(mrl_ptr) ) s->path = strdup(mrl_ptr+pathbegin+1); if( colon != slash ) { char buffer[pathbegin-hostend]; strncpy( buffer, mrl_ptr+hostend+1, pathbegin-hostend-1 ); buffer[pathbegin-hostend-1] = 0; s->port = atoi(buffer); if( s->port < 0 || s->port > 65535 ) s->port = 554; } free( mrl_ptr ); //fprintf( stderr, "got mrl: %s %i %s\n", s->host, s->port, s->path ); s->s = rtsp->pf_connect( rtsp->p_userdata, s->host, s->port ); if( s->s < 0 ) { //fprintf(stderr, "rtsp: failed to connect to '%s'\n", s->host); rtsp_close( rtsp ); return -1; } s->server_state = RTSP_CONNECTED; /* now lets send an options request. */ rtsp_schedule_field( rtsp, "CSeq: 1"); rtsp_schedule_field( rtsp, s->user_agent); rtsp_schedule_field( rtsp, "ClientChallenge: " "9e26d33f2984236010ef6253fb1887f7"); rtsp_schedule_field( rtsp, "PlayerStarttime: [28/03/2003:22:50:23 00:00]"); rtsp_schedule_field( rtsp, "CompanyID: KnKV4M4I/B2FjJ1TToLycw==" ); rtsp_schedule_field( rtsp, "GUID: 00000000-0000-0000-0000-000000000000" ); rtsp_schedule_field( rtsp, "RegionData: 0" ); rtsp_schedule_field( rtsp, "ClientID: " "Linux_2.4_6.0.9.1235_play32_RN01_EN_586" ); /*rtsp_schedule_field( rtsp, "Pragma: initiate-session" );*/ rtsp_request_options( rtsp, NULL ); return 0;}/* * closes an rtsp connection */void rtsp_close( rtsp_client_t *rtsp ){ if( rtsp->p_private->server_state ) { /* TODO: send a TEAROFF */ rtsp->pf_disconnect( rtsp->p_userdata ); } free( rtsp->p_private->path ); free( rtsp->p_private->host ); free( rtsp->p_private->mrl ); free( rtsp->p_private->session ); free( rtsp->p_private->user_agent ); free( rtsp->p_private->server ); rtsp_free_answers( rtsp ); rtsp_unschedule_all( rtsp ); free( rtsp->p_private );}/* * search in answers for tags. returns a pointer to the content * after the first matched tag. returns NULL if no match found. */char *rtsp_search_answers( rtsp_client_t *rtsp, const char *tag ){ char **answer; char *ptr; if( !rtsp->p_private->answers ) return NULL; answer = rtsp->p_private->answers; while(*answer) { if( !strncasecmp( *answer, tag, strlen(tag) ) ) { ptr = strchr(*answer, ':'); ptr++; while( *ptr == ' ' ) ptr++; return ptr; } answer++; } return NULL;}/* * session id management */void rtsp_set_session( rtsp_client_t *rtsp, const char *id ){ free( rtsp->p_private->session ); rtsp->p_private->session = strdup(id);}char *rtsp_get_session( rtsp_client_t *rtsp ){ return rtsp->p_private->session;}char *rtsp_get_mrl( rtsp_client_t *rtsp ){ return rtsp->p_private->mrl;}/* * schedules a field for transmission */void rtsp_schedule_field( rtsp_client_t *rtsp, const char *string ){ int i = 0; if( !string ) return; while( rtsp->p_private->scheduled[i] ) i++; rtsp->p_private->scheduled[i] = strdup(string);}/* * removes the first scheduled field which prefix matches string. */void rtsp_unschedule_field( rtsp_client_t *rtsp, const char *string ){ char **ptr = rtsp->p_private->scheduled; if( !string ) return; while( *ptr ) { if( !strncmp(*ptr, string, strlen(string)) ) break; } free( *ptr ); ptr++; do { *(ptr-1) = *ptr; } while( *ptr );}/* * unschedule all fields */void rtsp_unschedule_all( rtsp_client_t *rtsp ){ char **ptr; if( !rtsp->p_private->scheduled ) return; ptr = rtsp->p_private->scheduled; while( *ptr ) { free( *ptr ); *ptr = NULL; ptr++; }}/* * free answers */void rtsp_free_answers( rtsp_client_t *rtsp ){ char **answer; if( !rtsp->p_private->answers ) return; answer = rtsp->p_private->answers; while( *answer ) { free( *answer ); *answer = NULL; answer++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -