struct
{
mtime_t i_pts_delay;
+ mtime_t i_pts_jitter;
int i_cr_average;
} jitter;
} u;
typedef struct
{
- VLC_COMMON_MEMBERS
-
- /* */
+ vlc_thread_t thread;
input_thread_t *p_input;
es_out_t *p_out;
int64_t i_tmp_size_max;
/* */
bool b_delayed;
- ts_thread_t *p_thread;
+ ts_thread_t *p_ts;
/* */
bool b_input_paused;
static int TsChangePause( ts_thread_t *, bool b_source_paused, bool b_paused, mtime_t i_date );
static int TsChangeRate( ts_thread_t *, int i_src_rate, int i_rate );
-static void *TsRun( vlc_object_t * );
+static void *TsRun( void * );
static ts_storage_t *TsStorageNew( const char *psz_path, int64_t i_tmp_size_max );
static void TsStorageDelete( ts_storage_t * );
vlc_mutex_init_recursive( &p_sys->lock );
p_sys->b_delayed = false;
- p_sys->p_thread = NULL;
+ p_sys->p_ts = NULL;
TAB_INIT( p_sys->i_es, p_sys->pp_es );
p_sys->i_tmp_size_max = 50*1024*1024;
else
p_sys->i_tmp_size_max = __MAX( i_tmp_size_max, 1*1024*1024 );
- msg_Dbg( p_input, "using timeshift granularity of %d MBytes",
- (int)p_sys->i_tmp_size_max/(1024*1024) );
char *psz_tmp_path = var_CreateGetNonEmptyString( p_input, "input-timeshift-path" );
p_sys->psz_tmp_path = GetTmpPath( psz_tmp_path );
- msg_Dbg( p_input, "using timeshift path '%s'", p_sys->psz_tmp_path );
+
+ msg_Dbg( p_input, "using timeshift granularity of %d MiB, in path '%s'",
+ (int)p_sys->i_tmp_size_max/(1024*1024), p_sys->psz_tmp_path );
#if 0
#define S(t) msg_Err( p_input, "SIZEOF("#t")=%d", sizeof(t) )
if( p_sys->b_delayed )
{
- TsStop( p_sys->p_thread );
+ TsStop( p_sys->p_ts );
p_sys->b_delayed = false;
}
TAB_APPEND( p_sys->i_es, p_sys->pp_es, p_es );
if( p_sys->b_delayed )
- TsPushCmd( p_sys->p_thread, &cmd );
+ TsPushCmd( p_sys->p_ts, &cmd );
else
CmdExecuteAdd( p_sys->p_out, &cmd );
CmdInitSend( &cmd, p_es, p_block );
if( p_sys->b_delayed )
- TsPushCmd( p_sys->p_thread, &cmd );
+ TsPushCmd( p_sys->p_ts, &cmd );
else
i_ret = CmdExecuteSend( p_sys->p_out, &cmd) ;
CmdInitDel( &cmd, p_es );
if( p_sys->b_delayed )
- TsPushCmd( p_sys->p_thread, &cmd );
+ TsPushCmd( p_sys->p_ts, &cmd );
else
CmdExecuteDel( p_sys->p_out, &cmd );
{
es_out_sys_t *p_sys = p_out->p_sys;
- if( p_sys->b_delayed && TsHasCmd( p_sys->p_thread ) )
+ if( p_sys->b_delayed && TsHasCmd( p_sys->p_ts ) )
*pb_empty = false;
else
*pb_empty = es_out_GetEmpty( p_sys->p_out );
if( !p_sys->b_delayed )
TsStart( p_out );
if( p_sys->b_delayed )
- i_ret = TsChangePause( p_sys->p_thread, b_source_paused, b_paused, i_date );
+ i_ret = TsChangePause( p_sys->p_ts, b_source_paused, b_paused, i_date );
}
else
{
/* XXX we may do it BUT it would be better to finish the clock clean up+improvments
* and so be able to advertize correctly pace control property in access
* module */
- msg_Err( p_sys->p_input, "EsOutTimeshift does not work with streams that have space control" );
+ msg_Err( p_sys->p_input, "EsOutTimeshift does not work with streams that have pace control" );
}
}
if( !p_sys->b_delayed )
TsStart( p_out );
if( p_sys->b_delayed )
- i_ret = TsChangeRate( p_sys->p_thread, i_src_rate, i_rate );
+ i_ret = TsChangeRate( p_sys->p_ts, i_src_rate, i_rate );
}
else
{
/* XXX we may do it BUT it would be better to finish the clock clean up+improvments
* and so be able to advertize correctly pace control property in access
* module */
- msg_Err( p_sys->p_input, "EsOutTimeshift does not work with streams that have space control" );
+ msg_Err( p_sys->p_input, "EsOutTimeshift does not work with streams that have pace control" );
}
}
case ES_OUT_SET_ES_FMT:
case ES_OUT_SET_TIMES:
case ES_OUT_SET_JITTER:
+ case ES_OUT_SET_EOS:
{
ts_cmd_t cmd;
if( CmdInitControl( &cmd, i_query, args, p_sys->b_delayed ) )
return VLC_EGENERIC;
if( p_sys->b_delayed )
{
- TsPushCmd( p_sys->p_thread, &cmd );
+ TsPushCmd( p_sys->p_ts, &cmd );
return VLC_SUCCESS;
}
return CmdExecuteControl( p_sys->p_out, &cmd );
}
return es_out_Control( p_sys->p_out, ES_OUT_GET_ES_STATE, p_es->p_es, pb_enabled );
}
-
/* Special internal input control */
case ES_OUT_GET_EMPTY:
{
return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system );
}
+ case ES_OUT_GET_GROUP_FORCED:
+ {
+ int *pi_group = va_arg( args, int * );
+ return es_out_Control( p_sys->p_out, ES_OUT_GET_GROUP_FORCED, pi_group );
+ }
+
+
default:
msg_Err( p_sys->p_input, "Unknown es_out_Control query !" );
assert(0);
/*****************************************************************************
*
*****************************************************************************/
-static void TsDestructor( vlc_object_t *p_this )
+static void TsDestroy( ts_thread_t *p_ts )
{
- ts_thread_t *p_ts = (ts_thread_t*)p_this;
-
vlc_cond_destroy( &p_ts->wait );
vlc_mutex_destroy( &p_ts->lock );
+ free( p_ts );
}
static int TsStart( es_out_t *p_out )
{
assert( !p_sys->b_delayed );
- p_sys->p_thread = p_ts = vlc_custom_create( p_sys->p_input, sizeof(ts_thread_t),
- VLC_OBJECT_GENERIC, "es out timeshift" );
+ p_sys->p_ts = p_ts = calloc(1, sizeof(*p_ts));
if( !p_ts )
return VLC_EGENERIC;
p_ts->p_storage_r = NULL;
p_ts->p_storage_w = NULL;
- vlc_object_set_destructor( p_ts, TsDestructor );
-
p_sys->b_delayed = true;
- if( vlc_thread_create( p_ts, "es out timeshift",
- TsRun, VLC_THREAD_PRIORITY_INPUT ) )
+ if( vlc_clone( &p_ts->thread, TsRun, p_ts, VLC_THREAD_PRIORITY_INPUT ) )
{
- msg_Err( p_sys->p_input, "cannot create input thread" );
+ msg_Err( p_sys->p_input, "cannot create timeshift thread" );
- vlc_object_release( p_ts );
+ TsDestroy( p_ts );
p_sys->b_delayed = false;
return VLC_EGENERIC;
{
es_out_sys_t *p_sys = p_out->p_sys;
- if( !p_sys->b_delayed || !TsIsUnused( p_sys->p_thread ) )
+ if( !p_sys->b_delayed || !TsIsUnused( p_sys->p_ts ) )
return;
msg_Warn( p_sys->p_input, "es out timeshift: auto stop" );
- TsStop( p_sys->p_thread );
+ TsStop( p_sys->p_ts );
p_sys->b_delayed = false;
}
static void TsStop( ts_thread_t *p_ts )
{
- vlc_object_kill( p_ts );
- vlc_thread_join( p_ts );
+ vlc_cancel( p_ts->thread );
+ vlc_join( p_ts->thread, NULL );
vlc_mutex_lock( &p_ts->lock );
for( ;; )
TsStorageDelete( p_ts->p_storage_r );
vlc_mutex_unlock( &p_ts->lock );
- vlc_object_release( p_ts );
+ TsDestroy( p_ts );
}
static void TsPushCmd( ts_thread_t *p_ts, ts_cmd_t *p_cmd )
{
return i_ret;
}
-static void *TsRun( vlc_object_t *p_thread )
+static void *TsRun( void *p_data )
{
- ts_thread_t *p_ts = (ts_thread_t*)p_thread;
+ ts_thread_t *p_ts = p_data;
mtime_t i_buffering_date = -1;
for( ;; )
p_storage->i_file_size = 0;
p_storage->p_filew = GetTmpFile( &p_storage->psz_file, psz_tmp_path );
if( p_storage->psz_file )
- p_storage->p_filer = utf8_fopen( p_storage->psz_file, "rb" );
+ p_storage->p_filer = vlc_fopen( p_storage->psz_file, "rb" );
/* */
p_storage->i_cmd_w = 0;
p_storage->i_cmd_r = 0;
p_storage->i_cmd_max = 30000;
p_storage->p_cmd = malloc( p_storage->i_cmd_max * sizeof(*p_storage->p_cmd) );
- //fprintf( stderr, "\nSTORAGE name=%s size=%d kbytes\n", p_storage->psz_file, p_storage->i_cmd_max * sizeof(*p_storage->p_cmd) /1024 );
+ //fprintf( stderr, "\nSTORAGE name=%s size=%d KiB\n", p_storage->psz_file, p_storage->i_cmd_max * sizeof(*p_storage->p_cmd) /1024 );
if( !p_storage->p_cmd || !p_storage->p_filew || !p_storage->p_filer )
{
if( p_storage->psz_file )
{
- utf8_unlink( p_storage->psz_file );
+ vlc_unlink( p_storage->psz_file );
free( p_storage->psz_file );
}
p_block->i_pts = block.i_pts;
p_block->i_flags = block.i_flags;
p_block->i_length = block.i_length;
- p_block->i_rate = block.i_rate;
p_block->i_nb_samples = block.i_nb_samples;
p_block->i_buffer = fread( p_block->p_buffer, 1, block.i_buffer, p_storage->p_filer );
}
break;
case ES_OUT_RESET_PCR: /* no arg */
+ case ES_OUT_SET_EOS:
break;
case ES_OUT_SET_META: /* arg1=const vlc_meta_t* */
case ES_OUT_SET_JITTER:
{
mtime_t i_pts_delay = (mtime_t)va_arg( args, mtime_t );
+ mtime_t i_pts_jitter = (mtime_t)va_arg( args, mtime_t );
int i_cr_average = (int)va_arg( args, int );
p_cmd->u.control.u.jitter.i_pts_delay = i_pts_delay;
+ p_cmd->u.control.u.jitter.i_pts_jitter = i_pts_jitter;
p_cmd->u.control.u.jitter.i_cr_average = i_cr_average;
break;
}
p_cmd->u.control.u.int_i64.i_i64 );
case ES_OUT_RESET_PCR: /* no arg */
+ case ES_OUT_SET_EOS:
return es_out_Control( p_out, i_query );
case ES_OUT_SET_GROUP_META: /* arg1=int i_group arg2=const vlc_meta_t* */
p_cmd->u.control.u.times.i_length );
case ES_OUT_SET_JITTER:
return es_out_Control( p_out, i_query, p_cmd->u.control.u.jitter.i_pts_delay,
+ p_cmd->u.control.u.jitter.i_pts_jitter,
p_cmd->u.control.u.jitter.i_cr_average );
default:
{
/* Make sure that the path exists and is a directory */
struct stat s;
- const int i_ret = utf8_stat( psz_path, &s );
+ const int i_ret = vlc_stat( psz_path, &s );
- if( i_ret < 0 && !utf8_mkdir( psz_path, 0600 ) )
+ if( i_ret < 0 && !vlc_mkdir( psz_path, 0600 ) )
return psz_path;
else if( i_ret == 0 && ( s.st_mode & S_IFDIR ) )
return psz_path;
return strdup( "C:" );
}
#else
- psz_path = strdup( "/tmp" );
+ psz_path = strdup( DIR_SEP"tmp" );
#endif
return psz_path;
return NULL;
/* */
- fd = utf8_mkstemp( psz_name );
+ fd = vlc_mkstemp( psz_name );
*ppsz_file = psz_name;
if( fd < 0 )