struct vod_media_t
{
- int id;
-
/* VoD server */
vod_t *p_vod;
{
char *psz_rtsp_url;
- /* List of media */
- int i_media_id;
- int i_media;
- vod_media_t **media;
-
/* */
block_fifo_t *p_fifo_cmd;
};
/* rtsp delayed command (to avoid deadlock between vlm/httpd) */
typedef enum
{
- RTSP_CMD_TYPE_NONE, /* Exit requested */
-
- RTSP_CMD_TYPE_PLAY,
- RTSP_CMD_TYPE_PAUSE,
RTSP_CMD_TYPE_STOP,
- RTSP_CMD_TYPE_SEEK,
-#if 0
- RTSP_CMD_TYPE_REWIND,
- RTSP_CMD_TYPE_FORWARD,
-#endif
-
RTSP_CMD_TYPE_ADD,
RTSP_CMD_TYPE_DEL,
} rtsp_cmd_type_t;
typedef struct
{
int i_type;
- int i_media_id;
vod_media_t *p_media;
- char *psz_session;
char *psz_arg;
- int64_t i_arg;
} rtsp_cmd_t;
static vod_media_t *MediaNew( vod_t *, const char *, input_item_t * );
static void MediaAskDel ( vod_t *, vod_media_t * );
static void* CommandThread( vlc_object_t *p_this );
-static void CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *, const char *psz_session,
- int64_t i_arg, const char *psz_arg );
+static void CommandPush( vod_t *, rtsp_cmd_type_t, vod_media_t *,
+ const char *psz_arg );
/*****************************************************************************
* Open: Starts the RTSP server module
else
p_sys->psz_rtsp_url = psz_url;
- TAB_INIT( p_sys->i_media, p_sys->media );
- p_sys->i_media_id = 0;
-
p_vod->pf_media_new = MediaNew;
p_vod->pf_media_del = MediaAskDel;
p_sys->p_fifo_cmd = block_FifoNew();
- if( vlc_thread_create( p_vod, "rtsp vod thread", CommandThread,
- VLC_THREAD_PRIORITY_LOW ) )
+ if( vlc_thread_create( p_vod, CommandThread, VLC_THREAD_PRIORITY_LOW ) )
{
msg_Err( p_vod, "cannot spawn rtsp vod thread" );
block_FifoRelease( p_sys->p_fifo_cmd );
/* Stop command thread */
vlc_object_kill( p_vod );
- CommandPush( p_vod, RTSP_CMD_TYPE_NONE, NULL, NULL, 0, NULL );
vlc_thread_join( p_vod );
while( block_FifoCount( p_sys->p_fifo_cmd ) > 0 )
block_Release( p_block_cmd );
if ( cmd.i_type == RTSP_CMD_TYPE_DEL )
MediaDel(p_vod, cmd.p_media);
- free( cmd.psz_session );
free( cmd.psz_arg );
}
block_FifoRelease( p_sys->p_fifo_cmd );
- /* Check VLM is not buggy */
- if( p_sys->i_media > 0 )
- msg_Err( p_vod, "rtsp vod leaking %d medias", p_sys->i_media );
- TAB_CLEAN( p_sys->i_media, p_sys->media );
-
free( p_sys->psz_rtsp_url );
free( p_sys );
}
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 = calloc( 1, sizeof(vod_media_t) );
if( !p_media )
return NULL;
goto error;
}
+ msg_Dbg(p_vod, "adding media '%s'", psz_name);
+
+ CommandPush( p_vod, RTSP_CMD_TYPE_ADD, p_media, psz_name );
+ return p_media;
+
+error:
+ MediaDel(p_vod, p_media);
+ return NULL;
+}
+
+static void MediaSetup( vod_t *p_vod, vod_media_t *p_media,
+ const char *psz_name )
+{
+ vod_sys_t *p_sys = p_vod->p_sys;
char *psz_url;
if( asprintf( &psz_url, "%s%s", p_sys->psz_rtsp_url, psz_name ) < 0 )
- goto error;
+ return;
vlc_url_t url;
vlc_UrlParse( &url, psz_url, 0 );
vlc_UrlClean( &url );
if (p_media->rtsp == NULL)
- goto error;
+ return;
for (int i = 0; i < p_media->i_es; i++)
{
media_es_t *p_es = p_media->es[i];
p_es->rtsp_id = RtspAddId(p_media->rtsp, NULL, 0,
p_es->rtp_fmt.clock_rate, -1);
- if (p_es->rtsp_id == NULL)
- goto error;
}
-
- p_media->id = p_sys->i_media_id++;
-
- msg_Dbg(p_vod, "adding media '%s', id %i", psz_name, p_media->id);
-
- CommandPush( p_vod, RTSP_CMD_TYPE_ADD, p_media, NULL, 0, NULL );
- return p_media;
-
-error:
- MediaDel(p_vod, p_media);
- return NULL;
}
static void MediaAskDel ( vod_t *p_vod, vod_media_t *p_media )
{
- msg_Dbg( p_vod, "deleting media id %i", p_media->id );
- CommandPush( p_vod, RTSP_CMD_TYPE_DEL, p_media, NULL, 0, NULL );
+ msg_Dbg( p_vod, "deleting media" );
+ CommandPush( p_vod, RTSP_CMD_TYPE_DEL, p_media, NULL );
}
static void MediaDel( vod_t *p_vod, vod_media_t *p_media )
{
- vod_sys_t *p_sys = p_vod->p_sys;
-
- TAB_REMOVE( p_sys->i_media, p_sys->media, p_media );
+ (void) p_vod;
if (p_media->rtsp != NULL)
{
free( p_media );
}
-static void CommandPush( vod_t *p_vod, rtsp_cmd_type_t i_type, vod_media_t *p_media, const char *psz_session,
- int64_t i_arg, const char *psz_arg )
+static void CommandPush( vod_t *p_vod, rtsp_cmd_type_t i_type,
+ vod_media_t *p_media, const char *psz_arg )
{
rtsp_cmd_t cmd;
block_t *p_cmd;
- memset( &cmd, 0, sizeof(cmd) );
cmd.i_type = i_type;
cmd.p_media = p_media;
- if( p_media )
- cmd.i_media_id = p_media->id;
- if( psz_session )
- cmd.psz_session = strdup(psz_session);
- cmd.i_arg = i_arg;
if( psz_arg )
cmd.psz_arg = strdup(psz_arg);
+ else
+ cmd.psz_arg = NULL;
p_cmd = block_New( p_vod, sizeof(rtsp_cmd_t) );
memcpy( p_cmd->p_buffer, &cmd, sizeof(cmd) );
{
vod_t *p_vod = (vod_t*)p_this;
vod_sys_t *p_sys = p_vod->p_sys;
- int canc = vlc_savecancel ();
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;
+ int canc = vlc_savecancel ();
memcpy( &cmd, p_block_cmd->p_buffer, sizeof(cmd) );
block_Release( p_block_cmd );
- if( cmd.i_type == RTSP_CMD_TYPE_NONE )
- break;
-
- if ( cmd.i_type == RTSP_CMD_TYPE_ADD )
- {
- TAB_APPEND( p_sys->i_media, p_sys->media, cmd.p_media );
- goto next;
- }
-
- if ( cmd.i_type == RTSP_CMD_TYPE_DEL )
- {
- MediaDel(p_vod, cmd.p_media);
- goto next;
- }
-
/* */
- for( i = 0; i < p_sys->i_media; i++ )
- {
- if( p_sys->media[i]->id == cmd.i_media_id )
- break;
- }
- if( i >= p_sys->i_media )
- {
- goto next;
- }
- p_media = p_sys->media[i];
-
switch( cmd.i_type )
{
- case RTSP_CMD_TYPE_PLAY:
- vod_MediaControl( p_vod, p_media, cmd.psz_session,
- VOD_MEDIA_PLAY, cmd.psz_arg );
+ case RTSP_CMD_TYPE_ADD:
+ MediaSetup(p_vod, cmd.p_media, cmd.psz_arg);
break;
- case RTSP_CMD_TYPE_PAUSE:
- vod_MediaControl( p_vod, p_media, cmd.psz_session,
- VOD_MEDIA_PAUSE );
+ case RTSP_CMD_TYPE_DEL:
+ MediaDel(p_vod, cmd.p_media);
break;
-
case RTSP_CMD_TYPE_STOP:
- vod_MediaControl( p_vod, p_media, cmd.psz_session, VOD_MEDIA_STOP );
+ vod_MediaControl( p_vod, cmd.p_media, cmd.psz_arg, VOD_MEDIA_STOP );
break;
- case RTSP_CMD_TYPE_SEEK:
- vod_MediaControl( p_vod, p_media, cmd.psz_session,
- VOD_MEDIA_SEEK, cmd.i_arg );
- break;
-
-#if 0
- case RTSP_CMD_TYPE_REWIND:
- vod_MediaControl( p_vod, p_media, cmd.psz_session,
- VOD_MEDIA_REWIND, cmd.f_arg );
- break;
-
- case RTSP_CMD_TYPE_FORWARD:
- vod_MediaControl( p_vod, p_media, cmd.psz_session,
- VOD_MEDIA_FORWARD, cmd.f_arg );
- break;
-#endif
-
default:
break;
}
- next:
- free( cmd.psz_session );
free( cmd.psz_arg );
+ vlc_restorecancel (canc);
}
- vlc_restorecancel (canc);
return NULL;
}
return psz_sdp;
}
-/* TODO: add support in the VLM for queueing proper PLAY requests with
- * start and end times, fetch whether the input is seekable... and then
- * clean this up and remove the running argument */
-int vod_play(vod_media_t *p_media, const char *psz_session,
- int64_t start, int64_t end, bool running)
+int vod_check_range(vod_media_t *p_media, const char *psz_session,
+ int64_t start, int64_t end)
{
+ (void) psz_session;
+
if (p_media->i_length > 0 && (start > p_media->i_length
|| end > p_media->i_length))
return VLC_EGENERIC;
- /* We want to seek before unpausing, but it won't
- * work if the instance is not running yet. */
-
- if (!running)
- /* We're passing the #vod{} sout chain here */
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_PLAY, p_media,
- psz_session, 0, "vod");
- if (start >= 0)
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_SEEK, p_media,
- psz_session, start, NULL);
- if (running)
- /* This is the thing to do to unpause... */
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_PLAY, p_media,
- psz_session, 0, "vod");
-
return VLC_SUCCESS;
}
-void vod_pause(vod_media_t *p_media, const char *psz_session)
+/* TODO: add support in the VLM for queueing proper PLAY requests with
+ * start and end times, fetch whether the input is seekable... and then
+ * clean this up */
+void vod_play(vod_media_t *p_media, const char *psz_session,
+ int64_t *start, int64_t end)
+{
+ if (vod_check_range(p_media, psz_session, *start, end) != VLC_SUCCESS)
+ return;
+
+ /* We're passing the #vod{} sout chain here */
+ vod_MediaControl(p_media->p_vod, p_media, psz_session,
+ VOD_MEDIA_PLAY, "vod", start);
+}
+
+void vod_pause(vod_media_t *p_media, const char *psz_session, int64_t *npt)
{
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_PAUSE, p_media,
- psz_session, 0, NULL);
+ vod_MediaControl(p_media->p_vod, p_media, psz_session,
+ VOD_MEDIA_PAUSE, npt);
}
void vod_stop(vod_media_t *p_media, const char *psz_session)
{
- CommandPush(p_media->p_vod, RTSP_CMD_TYPE_STOP, p_media,
- psz_session, 0, NULL);
+ CommandPush(p_media->p_vod, RTSP_CMD_TYPE_STOP, p_media, psz_session);
}