📄 sap.c
字号:
} else { msg_Warn( p_obj, "unable to parse m field (2)"); FREE( psz_uri ); return VLC_EGENERIC; } psz_eof = strchr( psz_parse, ' ' ); if( psz_eof ) { *psz_eof = '\0'; psz_proto = strdup( psz_parse ); psz_parse = psz_eof + 1; p_sdp->i_media_type = atoi( psz_parse ); } else { msg_Dbg( p_obj, "incorrect m field, %s", p_sdp->psz_media ); p_sdp->i_media_type = 33; psz_proto = strdup( psz_parse ); } } if( psz_proto && !strncmp( psz_proto, "RTP/AVP", 7 ) ) { free( psz_proto ); psz_proto = strdup( "rtp" ); } if( psz_proto && !strncasecmp( psz_proto, "UDP", 3 ) ) { free( psz_proto ); psz_proto = strdup( "udp" ); } /* FIXME: HTTP support */ if( i_port == 0 ) { i_port = 1234; } if( ismult( psz_uri ) ) { asprintf( &p_sdp->psz_uri, "%s://@%s:%i", psz_proto, psz_uri, i_port ); } else { asprintf( &p_sdp->psz_uri, "%s://%s:%i", psz_proto, psz_uri, i_port ); } FREE( psz_uri ); FREE( psz_proto ); return VLC_SUCCESS;}/*********************************************************************** * ParseSDP : SDP parsing * ********************************************************************* * Validate SDP and parse all fields ***********************************************************************/static sdp_t * ParseSDP( vlc_object_t *p_obj, char* psz_sdp ){ sdp_t *p_sdp; vlc_bool_t b_invalid = VLC_FALSE; vlc_bool_t b_end = VLC_FALSE; if( psz_sdp == NULL ) { return NULL; } if( psz_sdp[0] != 'v' || psz_sdp[1] != '=' ) { msg_Warn( p_obj, "Bad packet" ); return NULL; } p_sdp = (sdp_t *)malloc( sizeof( sdp_t ) ); if( p_sdp == NULL ) return NULL; p_sdp->psz_sdp = strdup( psz_sdp ); if( p_sdp->psz_sdp == NULL ) { free( p_sdp ); return NULL; } p_sdp->psz_sessionname = NULL; p_sdp->psz_media = NULL; p_sdp->psz_connection = NULL; p_sdp->psz_uri = NULL; p_sdp->psz_address = NULL; p_sdp->psz_address_type= NULL; p_sdp->i_media = 0; p_sdp->i_attributes = 0; p_sdp->pp_attributes = NULL; while( *psz_sdp != '\0' && b_end == VLC_FALSE ) { char *psz_eol; char *psz_eof; char *psz_parse; char *psz_sess_id; while( *psz_sdp == '\r' || *psz_sdp == '\n' || *psz_sdp == ' ' || *psz_sdp == '\t' ) { psz_sdp++; } if( ( psz_eol = strchr( psz_sdp, '\n' ) ) == NULL ) { psz_eol = psz_sdp + strlen( psz_sdp ); b_end = VLC_TRUE; } if( psz_eol > psz_sdp && *( psz_eol - 1 ) == '\r' ) { psz_eol--; } if( psz_eol <= psz_sdp ) { break; } *psz_eol++ = '\0'; /* no space allowed between fields */ if( psz_sdp[1] != '=' ) { msg_Warn( p_obj, "invalid packet" ) ; FreeSDP( p_sdp ); return NULL; } /* Now parse each line */ switch( psz_sdp[0] ) { case( 'v' ): break; case( 's' ): p_sdp->psz_sessionname = strdup( &psz_sdp[2] ); break; case ( 'o' ): { int i_field = 0; /* o field is <username> <session id> <version> * <network type> <address type> <address> */#define GET_FIELD( store ) \ psz_eof = strchr( psz_parse, ' ' ); \ if( psz_eof ) \ { \ *psz_eof=0; store = strdup( psz_parse ); \ } \ else \ { \ if( i_field != 5 ) \ { \ b_invalid = VLC_TRUE; break; \ } \ else \ { \ store = strdup( psz_parse ); \ } \ }; \ psz_parse = psz_eof + 1; i_field++; psz_parse = &psz_sdp[2]; GET_FIELD( p_sdp->psz_username ); GET_FIELD( psz_sess_id ); p_sdp->i_session_id = atoll( psz_sess_id ); FREE( psz_sess_id ); GET_FIELD( psz_sess_id ); FREE( psz_sess_id ); GET_FIELD( p_sdp->psz_network_type ); GET_FIELD( p_sdp->psz_address_type ); GET_FIELD( p_sdp->psz_address ); break; } case( 'i' ): case( 'u' ): case( 'e' ): case( 'p' ): case( 't' ): case( 'r' ): break; case( 'a' ): /* attribute */ { char *psz_eon = strchr( &psz_sdp[2], ':' ); attribute_t *p_attr = malloc( sizeof( attribute_t ) ); /* Attribute with value */ if( psz_eon ) { *psz_eon++ = '\0'; p_attr->psz_field = strdup( &psz_sdp[2] ); p_attr->psz_value = strdup( psz_eon ); } else /* Attribute without value */ { p_attr->psz_field = strdup( &psz_sdp[2] ); p_attr->psz_value = NULL; } TAB_APPEND( p_sdp->i_attributes, p_sdp->pp_attributes, p_attr ); break; } case( 'm' ): /* Media announcement */ { /* If we have several medias, we pass the announcement to * LIVE.COM, so just count them */ p_sdp->i_media++; if( p_sdp->i_media == 1 ) { p_sdp->psz_media = strdup( &psz_sdp[2] ); } break; } case( 'c' ): { if( p_sdp->i_media > 1 ) break; p_sdp->psz_connection = strdup( &psz_sdp[2] ); break; } default: break; } if( b_invalid ) { FreeSDP( p_sdp ); return NULL; } psz_sdp = psz_eol; } return p_sdp;}static char *convert_from_utf8( struct services_discovery_t *p_sd, char *psz_unicode ){ char *psz_local, *psz_in, *psz_out; size_t ret, i_in, i_out; vlc_bool_t b_warn = VLC_FALSE; if( psz_unicode == NULL ) return NULL; psz_in = psz_unicode; i_in = strlen( psz_unicode );#ifndef MB_CUR_MAX i_out = 6 * i_in;#else i_out = MB_CUR_MAX * i_in;#endif psz_local = malloc( i_out + 1 ); if( psz_local == NULL ) return NULL; psz_out = psz_local; do { ret = vlc_iconv( p_sd->p_sys->iconvHandle, &psz_in, &i_in, &psz_out, &i_out); if( i_in ) { *psz_in = '?'; b_warn = VLC_TRUE; } else if( ret == (size_t)(-1) ) { msg_Err( p_sd, "character conversion failure : %s", strerror( errno ) ); free( psz_local ); return NULL; } } while( i_in ); if( b_warn ) msg_Warn( p_sd, "in \"%s\" : %s", psz_unicode, strerror( errno ) ); *psz_out = '\0'; return psz_local;}/*********************************************************************** * ismult: returns true if we have a multicast address ***********************************************************************/static vlc_bool_t ismult( char *psz_uri ){ char *psz_end; int i_value; /* IPv6 */ if( psz_uri[0] == '[') { if( strncasecmp( &psz_uri[1], "FF0" , 3) || ( !isalnum( psz_uri[1]) && strncasecmp( &psz_uri[2], "FF0" , 3) ) ) return( VLC_TRUE ); else return( VLC_FALSE ); } i_value = strtol( psz_uri, &psz_end, 0 ); if( *psz_end != '.' ) { return( VLC_FALSE ); } return ( ( i_value < 224 ) || ( i_value >= 240 ) ) ? VLC_FALSE : VLC_TRUE;}static int InitSocket( services_discovery_t *p_sd, char *psz_address, int i_port ){ int i_fd = net_OpenUDP( p_sd, psz_address, i_port, "", 0 ); if( i_fd != -1 ) { INSERT_ELEM( p_sd->p_sys->pi_fd, p_sd->p_sys->i_fd, p_sd->p_sys->i_fd, i_fd ); return VLC_SUCCESS; } return VLC_EGENERIC;}#ifdef HAVE_ZLIB_Hstatic int Decompress( unsigned char *psz_src, unsigned char **_dst, int i_len ){ int i_result, i_dstsize, n; unsigned char *psz_dst; z_stream d_stream; d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; i_result = inflateInit(&d_stream); if( i_result != Z_OK ) { printf( "inflateInit() failed. Result: %d\n", i_result ); return( -1 ); }#if 0 p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE; i_position = p_playlist->i_index; /* Gather the complete sdp file */ for( ;; ) { int i_read = stream_Read( p_demux->s, &p_sdp[i_sdp], i_sdp_max - i_sdp - 1 );#endif d_stream.next_in = (Bytef *)psz_src; d_stream.avail_in = i_len; n = 0; psz_dst = NULL; do { n++; psz_dst = (unsigned char *)realloc( psz_dst, n * 1000 ); d_stream.next_out = (Bytef *)&psz_dst[(n - 1) * 1000]; d_stream.avail_out = 1000; i_result = inflate(&d_stream, Z_NO_FLUSH); if( ( i_result != Z_OK ) && ( i_result != Z_STREAM_END ) ) { printf( "Zlib decompression failed. Result: %d\n", i_result ); return( -1 ); } } while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) && ( i_result != Z_STREAM_END ) ); i_dstsize = d_stream.total_out; inflateEnd( &d_stream ); *_dst = (unsigned char *)realloc( psz_dst, i_dstsize ); return i_dstsize;}#endifstatic void FreeSDP( sdp_t *p_sdp ){ int i; FREE( p_sdp->psz_sdp ); FREE( p_sdp->psz_sessionname ); FREE( p_sdp->psz_connection ); FREE( p_sdp->psz_media ); FREE( p_sdp->psz_uri ); FREE( p_sdp->psz_username ); FREE( p_sdp->psz_network_type ); FREE( p_sdp->psz_address ); FREE( p_sdp->psz_address_type ); for( i= p_sdp->i_attributes - 1; i >= 0 ; i-- ) { struct attribute_t *p_attr = p_sdp->pp_attributes[i]; FREE( p_sdp->pp_attributes[i]->psz_field ); FREE( p_sdp->pp_attributes[i]->psz_value ); REMOVE_ELEM( p_sdp->pp_attributes, p_sdp->i_attributes, i); FREE( p_attr ); } free( p_sdp );}static int RemoveAnnounce( services_discovery_t *p_sd, sap_announce_t *p_announce ){ int i; if( p_announce->p_sdp ) FreeSDP( p_announce->p_sdp ); if( p_announce->i_item_id > -1 ) { playlist_LockDelete( p_sd->p_sys->p_playlist, p_announce->i_item_id ); } for( i = 0; i< p_sd->p_sys->i_announces; i++) { if( p_sd->p_sys->pp_announces[i] == p_announce ) { REMOVE_ELEM( p_sd->p_sys->pp_announces, p_sd->p_sys->i_announces, i); break; } } free( p_announce ); return VLC_SUCCESS;}static vlc_bool_t IsSameSession( sdp_t *p_sdp1, sdp_t *p_sdp2 ){ /* A session is identified by * username, session_id, network type, address type and address */ if( p_sdp1->psz_username && p_sdp2->psz_username && p_sdp1->psz_network_type && p_sdp2->psz_network_type && p_sdp1->psz_address_type && p_sdp2->psz_address_type && p_sdp1->psz_address && p_sdp2->psz_address ) { if(!strcmp( p_sdp1->psz_username , p_sdp2->psz_username ) && !strcmp( p_sdp1->psz_network_type , p_sdp2->psz_network_type ) && !strcmp( p_sdp1->psz_address_type , p_sdp2->psz_address_type ) && !strcmp( p_sdp1->psz_address , p_sdp2->psz_address ) && p_sdp1->i_session_id == p_sdp2->i_session_id ) { return VLC_TRUE; } else { return VLC_FALSE; } } else { return VLC_FALSE; }}static void CacheLoad( services_discovery_t *p_sd ){ msg_Warn( p_sd, "Cache not implemented") ;}static void CacheSave( services_discovery_t *p_sd ){ msg_Warn( p_sd, "Cache not implemented") ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -