📄 rtp.c
字号:
p_sys->packet->p_buffer[ 5] = ( i_timestamp >> 16 )&0xff; p_sys->packet->p_buffer[ 6] = ( i_timestamp >> 8 )&0xff; p_sys->packet->p_buffer[ 7] = ( i_timestamp )&0xff; p_sys->packet->p_buffer[ 8] = p_sys->ssrc[0]; p_sys->packet->p_buffer[ 9] = p_sys->ssrc[1]; p_sys->packet->p_buffer[10] = p_sys->ssrc[2]; p_sys->packet->p_buffer[11] = p_sys->ssrc[3]; p_sys->packet->i_buffer = 12; p_sys->packet->i_dts = i_dts; p_sys->packet->i_length = p_buffer->i_length / i_packet; i_dts += p_sys->packet->i_length; p_sys->i_sequence++; } i_size = __MIN( i_data, p_sys->i_mtu - p_sys->packet->i_buffer ); memcpy( &p_sys->packet->p_buffer[p_sys->packet->i_buffer], p_data, i_size ); p_sys->packet->i_buffer += i_size; p_data += i_size; i_data -= i_size; } return VLC_SUCCESS;}static int AccessOutGrabberWrite( sout_access_out_t *p_access, block_t *p_buffer ){ sout_stream_t *p_stream = (sout_stream_t*)p_access->p_sys; //fprintf( stderr, "received buffer size=%d\n", p_buffer->i_buffer ); // while( p_buffer ) { block_t *p_next; AccessOutGrabberWriteBuffer( p_stream, p_buffer ); p_next = p_buffer->p_next; block_Release( p_buffer ); p_buffer = p_next; } return VLC_SUCCESS;}/**************************************************************************** * SAP: ****************************************************************************/static int SapSetup( sout_stream_t *p_stream ){ sout_stream_sys_t *p_sys = p_stream->p_sys; sout_instance_t *p_sout = p_stream->p_sout; announce_method_t *p_method = (announce_method_t *) malloc(sizeof(announce_method_t)); /* Remove the previous session */ if( p_sys->p_session != NULL) { sout_AnnounceUnRegister( p_sout, p_sys->p_session); sout_AnnounceSessionDestroy( p_sys->p_session ); p_sys->p_session = NULL; } p_method->i_type = METHOD_TYPE_SAP; p_method->psz_address = NULL; /* FIXME */ p_method->i_ip_version = 4; /* FIXME ! */ if( p_sys->i_es > 0 && p_sys->psz_sdp && *p_sys->psz_sdp ) { p_sys->p_session = sout_AnnounceRegisterSDP( p_sout, p_sys->psz_sdp, p_method ); } free( p_method ); return VLC_SUCCESS;}/***************************************************************************** File:****************************************************************************/static int FileSetup( sout_stream_t *p_stream ){ sout_stream_sys_t *p_sys = p_stream->p_sys; FILE *f; if( ( f = fopen( p_sys->psz_sdp_file, "wt" ) ) == NULL ) { msg_Err( p_stream, "cannot open file '%s' (%s)", p_sys->psz_sdp_file, strerror(errno) ); return VLC_EGENERIC; } fprintf( f, "%s", p_sys->psz_sdp ); fclose( f ); return VLC_SUCCESS;}/**************************************************************************** * HTTP: ****************************************************************************/static int HttpCallback( httpd_file_sys_t *p_args, httpd_file_t *, uint8_t *p_request, uint8_t **pp_data, int *pi_data );static int HttpSetup( sout_stream_t *p_stream, vlc_url_t *url){ sout_stream_sys_t *p_sys = p_stream->p_sys; p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host, url->i_port ); if( p_sys->p_httpd_host ) { p_sys->p_httpd_file = httpd_FileNew( p_sys->p_httpd_host, url->psz_path ? url->psz_path : "/", "application/sdp", NULL, NULL, HttpCallback, (void*)p_sys ); } if( p_sys->p_httpd_file == NULL ) { return VLC_EGENERIC; } return VLC_SUCCESS;}static int HttpCallback( httpd_file_sys_t *p_args, httpd_file_t *f, uint8_t *p_request, uint8_t **pp_data, int *pi_data ){ sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_args; vlc_mutex_lock( &p_sys->lock_sdp ); if( p_sys->psz_sdp && *p_sys->psz_sdp ) { *pi_data = strlen( p_sys->psz_sdp ); *pp_data = malloc( *pi_data ); memcpy( *pp_data, p_sys->psz_sdp, *pi_data ); } else { *pp_data = NULL; *pi_data = 0; } vlc_mutex_unlock( &p_sys->lock_sdp ); return VLC_SUCCESS;}/**************************************************************************** * RTSP: ****************************************************************************/static rtsp_client_t *RtspClientNew( sout_stream_t *p_stream, char *psz_session ){ rtsp_client_t *rtsp = malloc( sizeof( rtsp_client_t )); rtsp->psz_session = psz_session; rtsp->i_last = 0; rtsp->b_playing = VLC_FALSE; rtsp->i_id = 0; rtsp->id = NULL; rtsp->i_access = 0; rtsp->access = NULL; TAB_APPEND( p_stream->p_sys->i_rtsp, p_stream->p_sys->rtsp, rtsp ); return rtsp;}static rtsp_client_t *RtspClientGet( sout_stream_t *p_stream, char *psz_session ){ int i; for( i = 0; i < p_stream->p_sys->i_rtsp; i++ ) { if( !strcmp( p_stream->p_sys->rtsp[i]->psz_session, psz_session ) ) { return p_stream->p_sys->rtsp[i]; } } return NULL;}static void RtspClientDel( sout_stream_t *p_stream, rtsp_client_t *rtsp ){ int i; TAB_REMOVE( p_stream->p_sys->i_rtsp, p_stream->p_sys->rtsp, rtsp ); for( i = 0; i < rtsp->i_access; i++ ) { sout_AccessOutDelete( rtsp->access[i] ); } if( rtsp->id ) free( rtsp->id ); if( rtsp->access ) free( rtsp->access ); free( rtsp->psz_session ); free( rtsp );}static int RtspSetup( sout_stream_t *p_stream, vlc_url_t *url ){ sout_stream_sys_t *p_sys = p_stream->p_sys; fprintf( stderr, "rtsp setup: %s : %d / %s\n", url->psz_host, url->i_port, url->psz_path ); p_sys->p_rtsp_host = httpd_HostNew( VLC_OBJECT(p_stream), url->psz_host, url->i_port > 0 ? url->i_port : 554 ); if( p_sys->p_rtsp_host == NULL ) { return VLC_EGENERIC; } p_sys->psz_rtsp_path = strdup( url->psz_path ? url->psz_path : "/" ); p_sys->psz_rtsp_control = malloc (strlen( url->psz_host ) + 20 + strlen( p_sys->psz_rtsp_path ) + 1 ); sprintf( p_sys->psz_rtsp_control, "rtsp://%s:%d%s", url->psz_host, url->i_port > 0 ? url->i_port : 554, p_sys->psz_rtsp_path ); p_sys->p_rtsp_url = httpd_UrlNewUnique( p_sys->p_rtsp_host, p_sys->psz_rtsp_path, NULL, NULL ); if( p_sys->p_rtsp_url == 0 ) { return VLC_EGENERIC; } httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_DESCRIBE, RtspCallback, (void*)p_stream ); httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_PLAY, RtspCallback, (void*)p_stream ); httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_PAUSE, RtspCallback, (void*)p_stream ); httpd_UrlCatch( p_sys->p_rtsp_url, HTTPD_MSG_TEARDOWN, RtspCallback, (void*)p_stream ); return VLC_SUCCESS;}static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl, httpd_message_t *answer, httpd_message_t *query ){ sout_stream_t *p_stream = (sout_stream_t*)p_args; sout_stream_sys_t *p_sys = p_stream->p_sys; char *psz_destination = p_sys->psz_destination; char *psz_session = NULL; if( answer == NULL || query == NULL ) { return VLC_SUCCESS; } fprintf( stderr, "RtspCallback query: type=%d\n", query->i_type ); answer->i_proto = HTTPD_PROTO_RTSP; answer->i_version= query->i_version; answer->i_type = HTTPD_MSG_ANSWER; switch( query->i_type ) { case HTTPD_MSG_DESCRIBE: { char *psz_sdp = SDPGenerate( p_stream, psz_destination ? psz_destination : "0.0.0.0", VLC_TRUE ); answer->i_status = 200; answer->psz_status = strdup( "OK" ); httpd_MsgAdd( answer, "Content-type", "%s", "application/sdp" ); answer->p_body = psz_sdp; answer->i_body = strlen( psz_sdp ); break; } case HTTPD_MSG_PLAY: { rtsp_client_t *rtsp; /* for now only multicast so easy */ answer->i_status = 200; answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; psz_session = httpd_MsgGet( query, "Session" ); rtsp = RtspClientGet( p_stream, psz_session ); if( rtsp && !rtsp->b_playing ) { int i_id; /* FIXME */ rtsp->b_playing = VLC_TRUE; vlc_mutex_lock( &p_sys->lock_es ); for( i_id = 0; i_id < rtsp->i_id; i_id++ ) { sout_stream_id_t *id = rtsp->id[i_id]; int i; for( i = 0; i < p_sys->i_es; i++ ) { if( id == p_sys->es[i] ) break; } if( i >= p_sys->i_es ) continue; vlc_mutex_lock( &id->lock_rtsp ); TAB_APPEND( id->i_rtsp_access, id->rtsp_access, rtsp->access[i_id] ); vlc_mutex_unlock( &id->lock_rtsp ); } vlc_mutex_unlock( &p_sys->lock_es ); } break; } case HTTPD_MSG_PAUSE: /* FIXME */ return VLC_EGENERIC; case HTTPD_MSG_TEARDOWN: { rtsp_client_t *rtsp; /* for now only multicast so easy again */ answer->i_status = 200; answer->psz_status = strdup( "OK" ); answer->i_body = 0; answer->p_body = NULL; psz_session = httpd_MsgGet( query, "Session" ); rtsp = RtspClientGet( p_stream, psz_session ); if( rtsp ) { int i_id; vlc_mutex_lock( &p_sys->lock_es ); for( i_id = 0; i_id < rtsp->i_id; i_id++ ) { sout_stream_id_t *id = rtsp->id[i_id]; int i; for( i = 0; i < p_sys->i_es; i++ ) { if( id == p_sys->es[i] ) break; } if( i >= p_sys->i_es ) continue; vlc_mutex_lock( &id->lock_rtsp ); TAB_REMOVE( id->i_rtsp_access, id->rtsp_access, rtsp->access[i_id] ); vlc_mutex_unlock( &id->lock_rtsp ); } vlc_mutex_unlock( &p_sys->lock_es ); RtspClientDel( p_stream, rtsp ); } break; } default: return VLC_EGENERIC; } httpd_MsgAdd( answer, "Server", "VLC Server" ); httpd_MsgAdd( answer, "Content-Length", "%d", answer->i_body ); httpd_MsgAdd( answer, "Cseq", "%d", atoi( httpd_MsgGet( query, "Cseq" ) ) ); httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" ); if( psz_session ) { httpd_MsgAdd( answer, "Session", "%s;timeout=5", psz_session ); } return VLC_SUCCESS;}static int RtspCallbackId( httpd_callback_sys_t *p_args, httpd_client_t *cl, httpd_message_t *answer, httpd_message_t *query ){ sout_stream_id_t *id = (sout_stream_id_t*)p_args; sout_stream_t *p_stream = id->p_stream; sout_stream_sys_t *p_sys = p_stream->p_sys; char *psz_session = NULL; if( answer == NULL || query == NULL ) { return VLC_SUCCESS; } fprintf( stderr, "RtspCallback query: type=%d\n", query->i_type ); answer->i_proto = HTTPD_PROTO_RTSP; answer->i_version= query->i_version; answer->i_type = HTTPD_MSG_ANSWER; switch( query->i_type ) { case HTTPD_MSG_SETUP: { char *psz_transport = httpd_MsgGet( query, "Transport" ); fprintf( stderr, "HTTPD_MSG_SETUP: transport=%s\n", psz_transport ); if( strstr( psz_transport, "multicast" ) && id->psz_destination ) { fprintf( stderr, "HTTPD_MSG_SETUP: multicast\n" ); answer->i_status = 200; answer->psz_status = strdup( "OK" ); answer->i_body = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -