概述
代码从两大部分入手,一个telnet 的deamon。还有就是rtsp的实现部分 。结果发现,他们通过了一个桥梁vlm的media进行沟通。
- 当受到new MEDIANAME vod enabled 就建立一个media。
- 如果受到setup MEDIANAME input filename.mpg 就读入流准备分析,建立input流
- 当受到rtsp的请求后,就建立这个output流
这样,vod就和别的模块一致了。rtsp只是一种output流的module。
代码分析
1. /modules/control/telnet.c
/*****************************************************************************
* Run: main loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf ){
vlm_ExecuteCommand( p_sys->mediatheque, cl->buffer_read,
&message );
}
/*****************************************************************************
* Run: main loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf ){
vlm_ExecuteCommand( p_sys->mediatheque, cl->buffer_read,
&message );
}
2. /src/Misc/vlm.c
/*****************************************************************************
* vlm_ExecuteCommand:
*****************************************************************************/
int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command,
vlm_message_t **pp_message)
{
}
/*****************************************************************************
* vlm_ExecuteCommand:
*****************************************************************************/
int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command,
vlm_message_t **pp_message)
{
}
vlm_MediaNew( vlm_t *vlm, const char *psz_name, int i_type ){
vlm_media_t *media = malloc( sizeof( vlm_media_t ) );
}
*****************************************************
struct vlm_t
{
VLC_COMMON_MEMBERS
}
*****************************************************
struct vlm_t
{
VLC_COMMON_MEMBERS
vlc_mutex_t lock;
int i_media;
vlm_media_t **media;
vlm_media_t **media;
int i_vod;
vod_t *vod;
vod_t *vod;
int i_schedule;
vlm_schedule_t **schedule;
};
*****************************************************
int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
const char *psz_value ){
if( (p_input = input_CreateThread2( vlm, &media->item, psz_header
) ) )
{
while( !p_input->b_eof && !p_input->b_error ) msleep( 100000 );
input_StopThread( p_input );
input_DestroyThread( p_input );
vlc_object_detach( p_input );
vlc_object_destroy( p_input );
}
}
vlm_schedule_t **schedule;
};
*****************************************************
int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd,
const char *psz_value ){
if( (p_input = input_CreateThread2( vlm, &media->item, psz_header
) ) )
{
while( !p_input->b_eof && !p_input->b_error ) msleep( 100000 );
input_StopThread( p_input );
input_DestroyThread( p_input );
vlc_object_detach( p_input );
vlc_object_destroy( p_input );
}
}
3. /src/Input/input.c
input_thread_t *__input_CreateThread2( vlc_object_t *p_parent,
input_item_t *p_item,
char *psz_header )
{
input_thread_t *p_input = NULL; /* thread descriptor */
p_input = Create( p_parent, p_item, psz_header, VLC_FALSE );
/* Now we can attach our new input */
vlc_object_attach( p_input, p_parent );
/* Create thread and wait for its readiness. */
if( vlc_thread_create( p_input, "input", Run,
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
msg_Err( p_input, "cannot create input thread" );
vlc_object_detach( p_input );
vlc_object_destroy( p_input );
return NULL;
}
}
input_thread_t *__input_CreateThread2( vlc_object_t *p_parent,
input_item_t *p_item,
char *psz_header )
{
input_thread_t *p_input = NULL; /* thread descriptor */
p_input = Create( p_parent, p_item, psz_header, VLC_FALSE );
/* Now we can attach our new input */
vlc_object_attach( p_input, p_parent );
/* Create thread and wait for its readiness. */
if( vlc_thread_create( p_input, "input", Run,
VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
msg_Err( p_input, "cannot create input thread" );
vlc_object_detach( p_input );
vlc_object_destroy( p_input );
return NULL;
}
}
static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
char *psz_header, vlc_bool_t b_quick )
{
}
char *psz_header, vlc_bool_t b_quick )
{
}
/*****************************************************************************
* Run: main thread loop
* This is the "normal" thread that spawns the input processing chain,
* reads the stream, cleans up and waits
*****************************************************************************/
static int Run( input_thread_t *p_input )
{
}
=====================================================================================
4. /modules/misc/rtsp.c
static vod_media_t *MediaNew( vod_t *p_vod, const char *psz_name,
input_item_t *p_item )
{
vod_sys_t *p_sys = p_vod->p_sys;
vod_media_t *p_media = malloc( sizeof(vod_media_t) );
int i;
if( !p_media )
{
msg_Err( p_vod, "not enough memory" );
return NULL;
}
{
msg_Err( p_vod, "not enough memory" );
return NULL;
}
memset( p_media, 0, sizeof(vod_media_t) );
p_media->es = 0;
p_media->psz_mux = 0;
p_media->rtsp = 0;
p_media->b_raw = VLC_FALSE;
p_media->es = 0;
p_media->psz_mux = 0;
p_media->rtsp = 0;
p_media->b_raw = VLC_FALSE;
asprintf( &p_media->psz_rtsp_path, "%s%s", p_sys->psz_path, psz_name );
p_media->p_rtsp_url =
httpd_UrlNewUnique( p_sys->p_rtsp_host, p_media->psz_rtsp_path, NULL,
NULL, NULL );
p_media->p_rtsp_url =
httpd_UrlNewUnique( p_sys->p_rtsp_host, p_media->psz_rtsp_path, NULL,
NULL, NULL );
if( !p_media->p_rtsp_url )
{
msg_Err( p_vod, "cannot create RTSP url (%s)", p_media->psz_rtsp_path);
free( p_media->psz_rtsp_path );
free( p_media );
return NULL;
}
{
msg_Err( p_vod, "cannot create RTSP url (%s)", p_media->psz_rtsp_path);
free( p_media->psz_rtsp_path );
free( p_media );
return NULL;
}
msg_Dbg( p_vod, "created RTSP url: %s", p_media->psz_rtsp_path );
asprintf( &p_media->psz_rtsp_control_v4,
"a=control:rtsp://%%s:%d%s/trackID=%%d/r/n",
p_sys->i_port, p_media->psz_rtsp_path );
asprintf( &p_media->psz_rtsp_control_v6,
"a=control:rtsp://[%%s]:%d%s/trackID=%%d/r/n",
p_sys->i_port, p_media->psz_rtsp_path );
"a=control:rtsp://%%s:%d%s/trackID=%%d/r/n",
p_sys->i_port, p_media->psz_rtsp_path );
asprintf( &p_media->psz_rtsp_control_v6,
"a=control:rtsp://[%%s]:%d%s/trackID=%%d/r/n",
p_sys->i_port, p_media->psz_rtsp_path );
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_TEARDOWN,
RtspCallback, (void*)p_media );
}
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_TEARDOWN,
RtspCallback, (void*)p_media );
}
static int RtspCallback( httpd_callback_sys_t *p_args, httpd_client_t *cl,
httpd_message_t *answer, httpd_message_t *query )
{
switch( query->i_type )
{
case HTTPD_MSG_SETUP:
{
}
case HTTPD_MSG_PLAY:
{
p_rtsp = RtspClientGet( p_media, psz_session );
vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PLAY,
psz_output );
}
}
}
httpd_message_t *answer, httpd_message_t *query )
{
switch( query->i_type )
{
case HTTPD_MSG_SETUP:
{
}
case HTTPD_MSG_PLAY:
{
p_rtsp = RtspClientGet( p_media, psz_session );
vod_MediaControl( p_vod, p_media, psz_session, VOD_MEDIA_PLAY,
psz_output );
}
}
}
5. vlc_vod.h
static inline int vod_MediaControl( vod_t *p_vod, vod_media_t *p_media,
char *psz_id, int i_query, ... )
{
i_result = p_vod->pf_media_control( p_vod->p_data, p_media, psz_id,
i_query, args );
}
static inline int vod_MediaControl( vod_t *p_vod, vod_media_t *p_media,
char *psz_id, int i_query, ... )
{
i_result = p_vod->pf_media_control( p_vod->p_data, p_media, psz_id,
i_query, args );
}