* Preamble
*****************************************************************************/
#include <stdlib.h>
+#include <ctype.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
var_Get( p_input, "audio-desync", &val );
if( val.i_int < 0 ) p_input->i_pts_delay -= (val.i_int * 1000);
+ /* Update cr_average depending on the caching */
+ p_input->input.i_cr_average *= (10 * p_input->i_pts_delay / 200000);
+ p_input->input.i_cr_average /= 10;
+ if( p_input->input.i_cr_average <= 0 ) p_input->input.i_cr_average = 1;
+
/* Load master infos */
/* Init length */
if( !demux2_Control( p_input->input.p_demux, DEMUX_GET_LENGTH,
es_out_Control( p_input->p_es_out, ES_OUT_SET_MODE,
val.b_bool ? ES_OUT_MODE_ALL : ES_OUT_MODE_AUTO );
+ /* Inform the demuxer about waited group (needed only for DVB) */
+ if( val.b_bool )
+ demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP, -1 );
+ else
+ demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP,
+ (int) var_GetInteger( p_input, "program" ) );
+
if( p_input->p_sout )
{
if( p_input->p_sout->i_out_pace_nocontrol > 0 )
vlc_meta_Delete( p_meta );
}
}
+ else if( p_meta ) vlc_meta_Delete( p_meta );
msg_Dbg( p_input, "`%s' sucessfully opened",
p_input->input.p_item->psz_uri );
/*****************************************************************************
* Error: RunThread() error loop
*****************************************************************************
- * This function is called when an error occured during thread main's loop.
+ * This function is called when an error occurred during thread main's loop.
*****************************************************************************/
static void Error( input_thread_t *p_input )
{
vlc_value_t val;
int i;
- msg_Dbg( p_input, "closing `%s'",
- p_input->input.p_item->psz_uri );
+ msg_Dbg( p_input, "closing input" );
/* We are at the end */
p_input->i_state = END_S;
/* No need to force update, es_out does it if needed */
es_out_Control( p_input->p_es_out,
ES_OUT_SET_GROUP, val.i_int );
+
+ demux2_Control( p_input->input.p_demux, DEMUX_SET_GROUP, val.i_int );
break;
case INPUT_CONTROL_SET_ES:
int i_seekpoint_end = p_input->input.i_seekpoint_end -
p_input->input.i_seekpoint_offset;
- if( i_title_end >= 0 && i_seekpoint_end >=0 )
+ if( i_title_end >= 0 && i_seekpoint_end >= 0 )
{
if( p_demux->info.i_title > i_title_end ||
( p_demux->info.i_title == i_title_end &&
msg_Dbg( p_input, "`%s' gives access `%s' demux `%s' path `%s'",
psz_mrl, psz_access, psz_demux, psz_path );
+ /* Hack to allow udp://@:port syntax */
if( !psz_access ||
- ( strcmp( psz_access, "udp" ) && strcmp( psz_access, "udpstream" ) &&
- strcmp( psz_access, "udp4" ) && strcmp( psz_access, "udp6" ) &&
- strcmp( psz_access, "rtp" ) && strcmp( psz_access, "rtp4" ) &&
- strcmp( psz_access, "rtp6" ) ) ) // FIXME
+ (strncmp( psz_access, "udp", 3 ) && strncmp( psz_access, "rtp", 3 )) )
/* Find optional titles and seekpoints */
MRLSections( p_input, psz_path, &in->i_title_start, &in->i_title_end,
char *psz_access = NULL;
char *psz_demux = NULL;
char *psz_path = NULL;
- char *psz;
+ char *psz, *psz_check;
psz = strchr( psz_dup, ':' );
+ /* '@' not allowed in access/demux part */
+ psz_check = strchr( psz_dup, '@' );
+ if( psz_check && psz_check < psz ) psz = 0;
+
#if defined( WIN32 ) || defined( UNDER_CE )
if( psz - psz_dup == 1 )
{
- msg_Warn( p_input, "drive letter %c: found in source string",
- psz_dup[0] );
+ msg_Warn( p_input, "drive letter %c: found in source", *psz_dup );
psz_path = psz_dup;
}
else
if( psz )
{
*psz++ = '\0';
- if( psz[0] == '/' && psz[1] == '/' )
- psz += 2;
+ if( psz[0] == '/' && psz[1] == '/' ) psz += 2;
psz_path = psz;
psz_path = psz_dup;
}
- if( psz_access == NULL )
- *ppsz_access = "";
- else
- *ppsz_access = psz_access;
+ if( !psz_access ) *ppsz_access = "";
+ else *ppsz_access = psz_access;
- if( psz_demux == NULL )
- *ppsz_demux = "";
- else
- *ppsz_demux = psz_demux;
+ if( !psz_demux ) *ppsz_demux = "";
+ else *ppsz_demux = psz_demux;
- if( psz_path == NULL )
- *ppsz_path = "";
- else
- *ppsz_path = psz_path;
+ if( !psz_path ) *ppsz_path = "";
+ else *ppsz_path = psz_path;
}
/*****************************************************************************
* MRLSections: parse title and seekpoint info from the Media Resource Locator.
*
* Syntax:
- * [url][@[title-start][,chapter-start][-[title-end][,chapter-end]]]
+ * [url][@[title-start][:chapter-start][-[title-end][:chapter-end]]]
*****************************************************************************/
static void MRLSections( input_thread_t *p_input, char *psz_source,
int *pi_title_start, int *pi_title_end,
int *pi_chapter_start, int *pi_chapter_end )
{
- char *psz, *psz_end, *psz_next;
+ char *psz, *psz_end, *psz_next, *psz_check;
*pi_title_start = *pi_title_end = -1;
*pi_chapter_start = *pi_chapter_end = -1;
/* Start by parsing titles and chapters */
if( !psz_source || !( psz = strrchr( psz_source, '@' ) ) ) return;
- *psz++ = 0;
+ /* Check we are really dealing with a title/chapter section */
+ psz_check = psz + 1;
+ if( !*psz_check ) return;
+ if( isdigit(*psz_check) ) strtol( psz_check, &psz_check, 0 );
+ if( *psz_check != ':' && *psz_check != '-' && *psz_check ) return;
+ if( *psz_check == ':' && ++psz_check )
+ if( isdigit(*psz_check) ) strtol( psz_check, &psz_check, 0 );
+ if( *psz_check != '-' && *psz_check ) return;
+ if( *psz_check == '-' && ++psz_check )
+ if( isdigit(*psz_check) ) strtol( psz_check, &psz_check, 0 );
+ if( *psz_check != ':' && *psz_check ) return;
+ if( *psz_check == ':' && ++psz_check )
+ if( isdigit(*psz_check) ) strtol( psz_check, &psz_check, 0 );
+ if( *psz_check ) return;
/* Separate start and end */
+ *psz++ = 0;
if( ( psz_end = strchr( psz, '-' ) ) ) *psz_end++ = 0;
/* Look for the start title */