📄 rtsp.c
字号:
httpd_UrlDelete( p_media->p_rtsp_url ); free( p_media->psz_rtsp_path ); free( p_media ); return NULL; } httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallback, (void*)p_media ); httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_DESCRIBE, RtspCallback, (void*)p_media ); httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PLAY, RtspCallback, (void*)p_media ); httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_PAUSE, RtspCallback, (void*)p_media ); httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_GETPARAMETER, RtspCallback, (void*)p_media ); httpd_UrlCatch( p_media->p_rtsp_url, HTTPD_MSG_TEARDOWN, RtspCallback, (void*)p_media ); p_media->p_vod = p_vod; vlc_mutex_lock( &p_sys->lock_media ); TAB_APPEND( p_sys->i_media, p_sys->media, p_media ); vlc_mutex_unlock( &p_sys->lock_media ); vlc_mutex_init( &p_media->lock ); p_media->psz_session_name = strdup(""); p_media->psz_session_description = strdup(""); p_media->psz_session_url = strdup(""); p_media->psz_session_email = strdup(""); p_media->i_port_audio = 1234; p_media->i_port_video = 1236; p_media->i_port = 1238; p_media->i_payload_type = 96; p_media->i_sdp_id = mdate(); p_media->i_sdp_version = 1; p_media->i_length = input_item_GetDuration( p_item ); vlc_mutex_lock( &p_item->lock ); msg_Dbg( p_vod, "media has %i declared ES", p_item->i_es ); for( i = 0; i < p_item->i_es; i++ ) { MediaAddES( p_vod, p_media, p_item->es[i] ); } vlc_mutex_unlock( &p_item->lock ); return p_media;}static void MediaDel( vod_t *p_vod, vod_media_t *p_media ){ vod_sys_t *p_sys = p_vod->p_sys; msg_Dbg( p_vod, "deleting media: %s", p_media->psz_rtsp_path ); vlc_mutex_lock( &p_sys->lock_media ); TAB_REMOVE( p_sys->i_media, p_sys->media, p_media ); vlc_mutex_unlock( &p_sys->lock_media ); while( p_media->i_rtsp > 0 ) RtspClientDel( p_media, p_media->rtsp[0] ); TAB_CLEAN( p_media->i_rtsp, p_media->rtsp ); httpd_UrlDelete( p_media->p_rtsp_url ); free( p_media->psz_rtsp_path ); free( p_media->psz_rtsp_control_v6 ); free( p_media->psz_rtsp_control_v4 ); while( p_media->i_es ) MediaDelES( p_vod, p_media, &p_media->es[0]->fmt ); TAB_CLEAN( p_media->i_es, p_media->es ); vlc_mutex_destroy( &p_media->lock ); free( p_media->psz_session_name ); free( p_media->psz_session_description ); free( p_media->psz_session_url ); free( p_media->psz_session_email ); free( p_media->psz_mux ); free( p_media );}static int MediaAddES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt ){ media_es_t *p_es = malloc( sizeof(media_es_t) ); char *psz_urlc; if( !p_es ) return VLC_ENOMEM; memset( p_es, 0, sizeof(media_es_t) ); free( p_media->psz_mux ); p_media->psz_mux = NULL; /* TODO: update SDP, etc... */ if( asprintf( &psz_urlc, "%s/trackID=%d", p_media->psz_rtsp_path, p_media->i_es ) < 0 ) { free( p_es ); return VLC_ENOMEM; } msg_Dbg( p_vod, " - ES %4.4s (%s)", (char *)&p_fmt->i_codec, psz_urlc ); switch( p_fmt->i_codec ) { case VLC_FOURCC( 's', '1', '6', 'b' ): if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 ) { p_es->i_payload_type = 11; } else if( p_fmt->audio.i_channels == 2 && p_fmt->audio.i_rate == 44100 ) { p_es->i_payload_type = 10; } else { p_es->i_payload_type = p_media->i_payload_type++; } if( asprintf( &p_es->psz_rtpmap, "L16/%d/%d", p_fmt->audio.i_rate, p_fmt->audio.i_channels ) == -1 ) p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'u', '8', ' ', ' ' ): p_es->i_payload_type = p_media->i_payload_type++; if( asprintf( &p_es->psz_rtpmap, "L8/%d/%d", p_fmt->audio.i_rate, p_fmt->audio.i_channels ) == -1 ) p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'm', 'p', 'g', 'a' ): case VLC_FOURCC( 'm', 'p', '3', ' ' ): p_es->i_payload_type = 14; p_es->psz_rtpmap = strdup( "MPA/90000" ); break; case VLC_FOURCC( 'm', 'p', 'g', 'v' ): p_es->i_payload_type = 32; p_es->psz_rtpmap = strdup( "MPV/90000" ); break; case VLC_FOURCC( 'a', '5', '2', ' ' ): p_es->i_payload_type = p_media->i_payload_type++; if( asprintf( &p_es->psz_rtpmap, "ac3/%d", p_fmt->audio.i_rate ) == -1 ) p_es->psz_rtpmap = NULL; break; case VLC_FOURCC( 'H', '2', '6', '3' ): p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( "H263-1998/90000" ); break; case VLC_FOURCC( 'h', '2', '6', '4' ): p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( "H264/90000" ); p_es->psz_fmtp = NULL; /* FIXME AAAAAAAAAAAARRRRRRRRGGGG copied from stream_out/rtp.c */ if( p_fmt->i_extra > 0 ) { uint8_t *p_buffer = p_fmt->p_extra; int i_buffer = p_fmt->i_extra; char *p_64_sps = NULL; char *p_64_pps = NULL; char hexa[6+1]; while( i_buffer > 4 && p_buffer[0] == 0 && p_buffer[1] == 0 && p_buffer[2] == 0 && p_buffer[3] == 1 ) { const int i_nal_type = p_buffer[4]&0x1f; int i_offset; int i_size = 0; i_size = i_buffer; for( i_offset = 4; i_offset+3 < i_buffer ; i_offset++) { if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 0 && p_buffer[i_offset+3] == 1 ) { /* we found another startcode */ i_size = i_offset; break; } } if( i_nal_type == 7 ) { p_64_sps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 ); sprintf_hexa( hexa, &p_buffer[5], 3 ); } else if( i_nal_type == 8 ) { p_64_pps = vlc_b64_encode_binary( &p_buffer[4], i_size - 4 ); } i_buffer -= i_size; p_buffer += i_size; } /* */ if( p_64_sps && p_64_pps ) { if( asprintf( &p_es->psz_fmtp, "packetization-mode=1;profile-level-id=%s;" "sprop-parameter-sets=%s,%s;", hexa, p_64_sps, p_64_pps ) < 0 ) { free( p_64_sps ); free( p_64_pps ); free( psz_urlc ); free( p_es ); return VLC_ENOMEM; } } free( p_64_sps ); free( p_64_pps ); } if( !p_es->psz_fmtp ) p_es->psz_fmtp = strdup( "packetization-mode=1" ); break; case VLC_FOURCC( 'm', 'p', '4', 'v' ): p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( "MP4V-ES/90000" ); if( p_fmt->i_extra > 0 ) { char *p_hexa = malloc( 2 * p_fmt->i_extra + 1 ); sprintf_hexa( p_hexa, p_fmt->p_extra, p_fmt->i_extra ); if( asprintf( &p_es->psz_fmtp, "profile-level-id=3; config=%s;", p_hexa ) == -1 ) p_es->psz_fmtp = NULL; free( p_hexa ); } break; case VLC_FOURCC( 'm', 'p', '4', 'a' ): p_es->i_payload_type = p_media->i_payload_type++; if( asprintf( &p_es->psz_rtpmap, "mpeg4-generic/%d", p_fmt->audio.i_rate ) == -1 ) p_es->psz_rtpmap = NULL; if( p_fmt->i_extra > 0 ) { char *p_hexa = malloc( 2 * p_fmt->i_extra + 1 ); sprintf_hexa( p_hexa, p_fmt->p_extra, p_fmt->i_extra ); if( asprintf( &p_es->psz_fmtp, "streamtype=5; profile-level-id=15; mode=AAC-hbr; " "config=%s; SizeLength=13;IndexLength=3; " "IndexDeltaLength=3; Profile=1;", p_hexa ) == -1 ) p_es->psz_fmtp = NULL; free( p_hexa ); } break; case VLC_FOURCC( 'm', 'p', '2', 't' ): p_media->psz_mux = strdup("ts"); p_es->i_payload_type = 33; p_es->psz_rtpmap = strdup( "MP2T/90000" ); break; case VLC_FOURCC( 'm', 'p', '2', 'p' ): p_media->psz_mux = strdup("ps"); p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( "MP2P/90000" ); break; case VLC_FOURCC( 's', 'a', 'm', 'r' ): p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( p_fmt->audio.i_channels == 2 ? "AMR/8000/2" : "AMR/8000" ); p_es->psz_fmtp = strdup( "octet-align=1" ); break; case VLC_FOURCC( 's', 'a', 'w', 'b' ): p_es->i_payload_type = p_media->i_payload_type++; p_es->psz_rtpmap = strdup( p_fmt->audio.i_channels == 2 ? "AMR-WB/16000/2" : "AMR-WB/16000" ); p_es->psz_fmtp = strdup( "octet-align=1" ); break; default: msg_Err( p_vod, "cannot add this stream (unsupported " "codec: %4.4s)", (char*)&p_fmt->i_codec ); free( psz_urlc ); free( p_es ); return VLC_EGENERIC; } p_es->p_rtsp_url = httpd_UrlNewUnique( p_vod->p_sys->p_rtsp_host, psz_urlc, NULL, NULL, NULL ); if( !p_es->p_rtsp_url ) { msg_Err( p_vod, "cannot create RTSP url (%s)", psz_urlc ); free( psz_urlc ); free( p_es ); return VLC_EGENERIC; } free( psz_urlc ); httpd_UrlCatch( p_es->p_rtsp_url, HTTPD_MSG_SETUP, RtspCallbackES, (void*)p_es ); httpd_UrlCatch( p_es->p_rtsp_url, HTTPD_MSG_TEARDOWN, RtspCallbackES, (void*)p_es ); httpd_UrlCatch( p_es->p_rtsp_url, HTTPD_MSG_PLAY, RtspCallbackES, (void*)p_es ); httpd_UrlCatch( p_es->p_rtsp_url, HTTPD_MSG_PAUSE, RtspCallbackES, (void*)p_es ); es_format_Copy( &p_es->fmt, p_fmt ); p_es->p_vod = p_vod; p_es->p_media = p_media;#if 0 /* Choose the port */ if( p_fmt->i_cat == AUDIO_ES && p_media->i_port_audio > 0 ) { p_es->i_port = p_media->i_port_audio; p_media->i_port_audio = 0; } else if( p_fmt->i_cat == VIDEO_ES && p_media->i_port_video > 0 ) { p_es->i_port = p_media->i_port_video; p_media->i_port_video = 0; } while( !p_es->i_port ) { if( p_media->i_port != p_media->i_port_audio && p_media->i_port != p_media->i_port_video ) { p_es->i_port = p_media->i_port; p_media->i_port += 2; break; } p_media->i_port += 2; }#else p_es->i_port = 0;#endif vlc_mutex_lock( &p_media->lock ); TAB_APPEND( p_media->i_es, p_media->es, p_es ); vlc_mutex_unlock( &p_media->lock ); p_media->i_sdp_version++; return VLC_SUCCESS;}static void MediaDelES( vod_t *p_vod, vod_media_t *p_media, es_format_t *p_fmt){ media_es_t *p_es = NULL; int i; /* Find the ES */ for( i = 0; i < p_media->i_es; i++ ) { if( p_media->es[i]->fmt.i_cat == p_fmt->i_cat && p_media->es[i]->fmt.i_codec == p_fmt->i_codec && p_media->es[i]->fmt.i_id == p_fmt->i_id ) { p_es = p_media->es[i]; } } if( !p_es ) return; msg_Dbg( p_vod, " - Removing ES %4.4s", (char *)&p_fmt->i_codec ); vlc_mutex_lock( &p_media->lock ); TAB_REMOVE( p_media->i_es, p_media->es, p_es ); vlc_mutex_unlock( &p_media->lock ); free( p_es->psz_rtpmap ); free( p_es->psz_fmtp ); p_media->i_sdp_version++; if( p_es->p_rtsp_url ) httpd_UrlDelete( p_es->p_rtsp_url ); es_format_Clean( &p_es->fmt ); free( p_es );}/* */typedef struct{ int i_type; int i_media_id; //vod_media_t *p_media; char *psz_session; char *psz_arg; double f_arg;} rtsp_cmd_t;static void CommandPush( vod_t *p_vod, rtsp_cmd_type_t i_type, vod_media_t *p_media, const char *psz_session, double f_arg, const char *psz_arg ){ rtsp_cmd_t cmd; block_t *p_cmd; memset( &cmd, 0, sizeof(cmd) ); cmd.i_type = i_type; if( p_media ) cmd.i_media_id = p_media->id; if( psz_session ) cmd.psz_session = strdup(psz_session); cmd.f_arg = f_arg; if( psz_arg ) cmd.psz_arg = strdup(psz_arg); p_cmd = block_New( p_vod, sizeof(rtsp_cmd_t) ); memcpy( p_cmd->p_buffer, &cmd, sizeof(cmd) ); block_FifoPut( p_vod->p_sys->p_fifo_cmd, p_cmd );}static void* CommandThread( vlc_object_t *p_this ){ vod_t *p_vod = (vod_t*)p_this; vod_sys_t *p_sys = p_vod->p_sys; while( vlc_object_alive (p_vod) ) { block_t *p_block_cmd = block_FifoGet( p_sys->p_fifo_cmd ); rtsp_cmd_t cmd; vod_media_t *p_media = NULL; int i; if( !p_block_cmd ) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -