/* Attachments */
DEMUX_GET_ATTACHMENTS, /* arg1=input_attachment_t***, int* res=can fail */
+ /* RECORD you should accept it only if the stream can be recorded without
+ * any modification or header addition. */
+ DEMUX_CAN_RECORD, /* arg1=bool* res=can fail(assume false) */
+ DEMUX_SET_RECORD_STATE, /* arg1=bool res=can fail */
+
+
/* II. Specific access_demux queries */
- DEMUX_CAN_PAUSE, /* arg1= bool* can fail (assume false)*/
+ DEMUX_CAN_PAUSE = 0x1000, /* arg1= bool* can fail (assume false)*/
DEMUX_SET_PAUSE_STATE, /* arg1= bool can fail */
DEMUX_GET_PTS_DELAY, /* arg1= int64_t* cannot fail */
INPUT_GET_ATTACHMENT, /* arg1=input_attachment_t**, arg2=char* res=can fail */
/* On the fly input slave */
- INPUT_ADD_SLAVE /* arg1= char * */
+ INPUT_ADD_SLAVE, /* arg1= char * */
+
+ /* On the fly record while playing */
+ INPUT_SET_RECORD_STATE, /* arg1=bool res=can fail */
+ INPUT_GET_RECORD_STATE, /* arg1=bool* res=can fail */
};
VLC_EXPORT( int, input_vaControl,( input_thread_t *, int i_query, va_list ) );
STREAM_CONTROL_ACCESS, /* arg1= int i_access_query, args res: can fail
if access unreachable or access control answer */
- STREAM_GET_CONTENT_TYPE, /**< arg1= char ** res=can file */
+ STREAM_GET_CONTENT_TYPE, /**< arg1= char ** res=can fail */
+
+ /* SET_RECORD:
+ * XXX only data read through stream_Read/Block will be recorded */
+ STREAM_SET_RECORD_STATE, /**< arg1=bool, arg2=const char *psz_ext (if arg1 is true) res=can fail */
};
VLC_EXPORT( int, stream_Read, ( stream_t *s, void *p_read, int i_read ) );
{
osd_MenuActivate( VLC_OBJECT(p_intf) );
}
+ else if( i_action == ACTIONID_RECORD )
+ {
+ if( var_GetBool( p_input, "can-record" ) )
+ {
+ const bool b_record = !var_GetBool( p_input, "record" );
+
+ if( b_record )
+ vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording") );
+ else
+ vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Recording done") );
+ var_SetBool( p_input, "record", b_record );
+ }
+ }
}
if( p_vout )
vlc_object_release( p_vout );
/* */
bool b_meta;
+
+ /* */
+ bool b_start_record;
};
static int Demux ( demux_t *p_demux );
p_sys->b_udp_out = false;
p_sys->i_ts_read = 50;
p_sys->csa = NULL;
+ p_sys->b_start_record = false;
/* Init PAT handler */
pat = &p_sys->pid[0];
}
}
+ if( p_sys->b_start_record )
+ {
+ /* Enable recording once synchronized */
+ stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, true, "ts" );
+ p_sys->b_start_record = false;
+ }
+
if( p_sys->b_udp_out )
{
memcpy( &p_sys->buffer[i_pkt * p_sys->i_packet_size],
{
demux_sys_t *p_sys = p_demux->p_sys;
double f, *pf;
+ bool b_bool, *pb_bool;
int64_t i64;
int64_t *pi64;
int i_int;
return VLC_SUCCESS;
}
+ case DEMUX_CAN_RECORD:
+ pb_bool = (bool*)va_arg( args, bool * );
+ *pb_bool = true;
+ return VLC_SUCCESS;
+
+ case DEMUX_SET_RECORD_STATE:
+ b_bool = (bool)va_arg( args, int );
+
+ if( !b_bool )
+ stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, false );
+ p_sys->b_start_record = b_bool;
+ return VLC_SUCCESS;
+
case DEMUX_GET_FPS:
case DEMUX_SET_TIME:
default:
input_item_t *p_item = input_GetItem( THEMIM->getInput() );
i_input_id = p_item->i_id;
- if( var_Type( THEMIM->getInput(), "record-toggle" ) == VLC_VAR_VOID )
- recordButton->setVisible( true );
- else
- recordButton->setVisible( false );
+ recordButton->setVisible( var_GetBool( THEMIM->getInput(), "can-record" ) );
}
else
+ {
recordButton->setVisible( false );
+ }
ABButton->setEnabled( enable );
recordButton->setEnabled( enable );
if( p_input )
{
/* This method won't work fine if the stream can't be cut anywhere */
- if( var_Type( p_input, "record-toggle" ) == VLC_VAR_VOID )
- var_TriggerCallback( p_input, "record-toggle" );
+ const bool b_recording = var_GetBool( p_input, "record" );
+ var_SetBool( p_input, "record", !b_recording );
#if 0
else
{
int *pi_bkmk;
int i_int, *pi_int;
+ bool b_bool, *pb_bool;
double f, *pf;
int64_t i_64, *pi_64;
return VLC_EGENERIC;
}
+ case INPUT_SET_RECORD_STATE:
+ b_bool = (bool)va_arg( args, int );
+ var_SetBool( p_input, "record", b_bool );
+ return VLC_SUCCESS;
+
+ case INPUT_GET_RECORD_STATE:
+ pb_bool = (bool*)va_arg( args, bool* );
+ *pb_bool = var_GetBool( p_input, "record" );
+ return VLC_SUCCESS;
default:
msg_Err( p_input, "unknown query in input_vaControl" );
vlc_mutex_unlock( &p_vout->picture_lock );
}
-
-static void optimize_video_pts( decoder_t *p_dec )
+static void DecoderOptimizePtsDelay( decoder_t *p_dec )
{
- picture_t * oldest_pict = NULL;
- picture_t * youngest_pict = NULL;
- int i;
+ input_thread_t *p_input = p_dec->p_owner->p_input;
+ vout_thread_t *p_vout = p_dec->p_owner->p_vout;
+ input_thread_private_t *p_priv = p_input->p;
- input_thread_t * p_input = p_dec->p_owner->p_input;
- vout_thread_t * p_vout = p_dec->p_owner->p_vout;
- input_thread_private_t * p_priv = p_input->p;
+ picture_t *p_old = NULL;
+ picture_t *p_young = NULL;
+ int i;
/* Enable with --auto-adjust-pts-delay */
- if( !p_priv->pts_adjust.auto_adjust ) return;
+ if( !p_priv->pts_adjust.b_auto_adjust )
+ return;
for( i = 0; i < I_RENDERPICTURES; i++ )
{
- picture_t * pic = PP_RENDERPICTURE[i];
- if( pic->i_status != READY_PICTURE )
+ picture_t *p_pic = PP_RENDERPICTURE[i];
+
+ if( p_pic->i_status != READY_PICTURE )
continue;
- if( !oldest_pict || pic->date < oldest_pict->date )
- oldest_pict = pic;
- if( !youngest_pict || pic->date > youngest_pict->date )
- youngest_pict = pic;
+ if( !p_old || p_pic->date < p_old->date )
+ p_old = p_pic;
+ if( !p_young || p_pic->date > p_young->date )
+ p_young = p_pic;
}
- if( !youngest_pict || !oldest_pict )
+ if( !p_young || !p_old )
return;
/* Try to find if we can reduce the pts
* pts<->dts delay in the muxed stream. That is
* why we may end up in having a negative pts_delay,
* to compensate that artificial delay. */
- mtime_t buffer_size = youngest_pict->date - oldest_pict->date;
- int64_t pts_slide = 0;
- if( buffer_size < 10000 )
+ const mtime_t i_buffer_length = p_young->date - p_old->date;
+ int64_t i_pts_slide = 0;
+ if( i_buffer_length < 10000 )
{
if( p_priv->pts_adjust.i_num_faulty > 10 )
{
- pts_slide = __MAX(p_input->i_pts_delay *3 / 2, 10000);
+ i_pts_slide = __MAX(p_input->i_pts_delay *3 / 2, 10000);
p_priv->pts_adjust.i_num_faulty = 0;
}
- if( p_priv->pts_adjust.to_high )
+ if( p_priv->pts_adjust.b_to_high )
{
- p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high;
+ p_priv->pts_adjust.b_to_high = !p_priv->pts_adjust.b_to_high;
p_priv->pts_adjust.i_num_faulty = 0;
}
p_priv->pts_adjust.i_num_faulty++;
}
- else if( buffer_size > 100000 )
+ else if( i_buffer_length > 100000 )
{
if( p_priv->pts_adjust.i_num_faulty > 25 )
{
- pts_slide = -buffer_size/2;
+ i_pts_slide = -i_buffer_length/2;
p_priv->pts_adjust.i_num_faulty = 0;
}
- if( p_priv->pts_adjust.to_high )
+ if( p_priv->pts_adjust.b_to_high )
{
- p_priv->pts_adjust.to_high = !p_priv->pts_adjust.to_high;
+ p_priv->pts_adjust.b_to_high = !p_priv->pts_adjust.b_to_high;
p_priv->pts_adjust.i_num_faulty = 0;
}
p_priv->pts_adjust.i_num_faulty++;
}
- if( pts_slide )
+ if( i_pts_slide != 0 )
{
- mtime_t origi_delay = p_input->i_pts_delay;
+ const mtime_t i_pts_delay_org = p_input->i_pts_delay;
- p_input->i_pts_delay += pts_slide;
+ p_input->i_pts_delay += i_pts_slide;
/* Don't play with the pts delay for more than -2<->3sec */
if( p_input->i_pts_delay < -2000000 )
p_input->i_pts_delay = -2000000;
else if( p_input->i_pts_delay > 3000000 )
p_input->i_pts_delay = 3000000;
- pts_slide = p_input->i_pts_delay - origi_delay;
+ i_pts_slide = p_input->i_pts_delay - i_pts_delay_org;
msg_Dbg( p_input, "Sliding the pts by %dms pts delay at %dms picture buffer was %dms",
- (int)pts_slide/1000, (int)p_input->i_pts_delay/1000, (int)buffer_size/1000);
+ (int)i_pts_slide/1000, (int)p_input->i_pts_delay/1000, (int)i_buffer_length/1000);
vlc_mutex_lock( &p_vout->picture_lock );
/* Slide all the picture */
for( i = 0; i < I_RENDERPICTURES; i++ )
- PP_RENDERPICTURE[i]->date += pts_slide;
+ PP_RENDERPICTURE[i]->date += i_pts_slide;
/* FIXME: slide aout/spu */
vlc_mutex_unlock( &p_vout->picture_lock );
-
}
}
vout_DatePicture( p_vout, p_pic, p_pic->date );
- optimize_video_pts( p_dec );
+ DecoderOptimizePtsDelay( p_dec );
vout_DisplayPicture( p_vout, p_pic );
}
case DEMUX_GET_TITLE_INFO:
case DEMUX_SET_GROUP:
case DEMUX_GET_ATTACHMENTS:
+ case DEMUX_CAN_RECORD:
+ case DEMUX_SET_RECORD_STATE:
return VLC_EGENERIC;
default:
case STREAM_CONTROL_ACCESS:
case STREAM_GET_CONTENT_TYPE:
+ case STREAM_SET_RECORD_STATE:
return VLC_EGENERIC;
default:
* - seekable (if you can seek, it doesn't say if 'bar display' has be shown
* or not, for that check position != 0.0)
* - can-pause
+ * - can-record (if a stream can be recorded while playing)
* - teletext-es to get the index of spu track that is teletext --1 if no teletext)
* * For intf callback upon changes
* - intf-change
p_input->p->i_title_offset = p_input->p->i_seekpoint_offset = 0;
p_input->i_state = INIT_S;
p_input->p->i_rate = INPUT_RATE_DEFAULT;
+ p_input->p->b_recording = false;
TAB_INIT( p_input->p->i_bookmark, p_input->p->bookmark );
TAB_INIT( p_input->p->i_attachment, p_input->p->attachment );
p_input->p->p_es_out = NULL;
/* Create Objects variables for public Get and Set */
input_ControlVarInit( p_input );
+ /* */
+ p_input->p->pts_adjust.b_auto_adjust = var_GetBool( p_input, "auto-adjust-pts-delay" );
p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" );
if( !p_input->b_preparsing )
case INPUT_CONTROL_SET_POSITION_OFFSET:
{
double f_pos;
+
+ if( p_input->p->b_recording )
+ {
+ msg_Err( p_input, "INPUT_CONTROL_SET_POSITION(_OFFSET) ignored while recording" );
+ break;
+ }
if( i_type == INPUT_CONTROL_SET_POSITION )
{
f_pos = val.f_float;
int64_t i_time;
int i_ret;
+ if( p_input->p->b_recording )
+ {
+ msg_Err( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) ignored while recording" );
+ break;
+ }
+
if( i_type == INPUT_CONTROL_SET_TIME )
{
i_time = val.i_time;
case INPUT_CONTROL_SET_TITLE:
case INPUT_CONTROL_SET_TITLE_NEXT:
case INPUT_CONTROL_SET_TITLE_PREV:
+ if( p_input->p->b_recording )
+ {
+ msg_Err( p_input, "INPUT_CONTROL_SET_TITLE(*) ignored while recording" );
+ break;
+ }
if( p_input->p->input.b_title_demux &&
p_input->p->input.i_title > 0 )
{
case INPUT_CONTROL_SET_SEEKPOINT:
case INPUT_CONTROL_SET_SEEKPOINT_NEXT:
case INPUT_CONTROL_SET_SEEKPOINT_PREV:
+ if( p_input->p->b_recording )
+ {
+ msg_Err( p_input, "INPUT_CONTROL_SET_SEEKPOINT(*) ignored while recording" );
+ break;
+ }
+
if( p_input->p->input.b_title_demux &&
p_input->p->input.i_title > 0 )
{
}
break;
+ case INPUT_CONTROL_SET_RECORD_STATE:
+ if( p_input->p->input.b_can_record )
+ {
+ if( !!p_input->p->b_recording != !!val.b_bool )
+ {
+ if( demux_Control( p_input->p->input.p_demux,
+ DEMUX_SET_RECORD_STATE, val.b_bool ) )
+ val.b_bool = false;
+
+ p_input->p->b_recording = val.b_bool;
+ }
+
+ var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL );
+
+ b_force_update = true;
+ }
+ break;
+
case INPUT_CONTROL_SET_BOOKMARK:
default:
msg_Err( p_input, "not yet implemented" );
*****************************************************************************/
static input_source_t *InputSourceNew( input_thread_t *p_input )
{
- (void)p_input;
- input_source_t *in = (input_source_t*) malloc( sizeof( input_source_t ) );
+ VLC_UNUSED(p_input);
+ input_source_t *in = malloc( sizeof( input_source_t ) );
if( in )
memset( in, 0, sizeof( input_source_t ) );
return in;
goto error;
}
+ if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_record ) )
+ in->b_can_record = false;
+ var_SetBool( p_input, "can-record", in->b_can_record );
+
/* Get title from demux */
if( !p_input->b_preparsing && in->i_title <= 0 )
{
bool b_can_pause;
bool b_can_pace_control;
bool b_can_rate_control;
+ bool b_can_record;
bool b_rescale_ts;
bool b_eof; /* eof of demuxer */
bool b_can_rate_control;
int i_rate;
+ bool b_recording;
/* */
int64_t i_start; /* :start-time,0 by default */
int64_t i_stop; /* :stop-time, 0 if none */
input_source_t **slave;
/* pts delay fixup */
- struct {
+ struct
+ {
int i_num_faulty;
- bool to_high;
- bool auto_adjust;
+ bool b_to_high;
+ bool b_auto_adjust;
} pts_adjust;
/* Stats counters */
INPUT_CONTROL_SET_SPU_DELAY,
INPUT_CONTROL_ADD_SLAVE,
+
+ INPUT_CONTROL_SET_RECORD_STATE,
};
/* Internal helpers */
# include "config.h"
#endif
+#include <dirent.h>
+
#include <vlc_common.h>
+#include <vlc_charset.h>
+#include <vlc_strings.h>
+#include <vlc_osd.h>
#include <assert.h>
/* Preparse mode ? */
bool b_quick;
+
+ /* */
+ struct
+ {
+ bool b_active;
+
+ FILE *f; /* TODO it could be replaced by access_output_t one day */
+ } record;
};
/* Method 1: */
static void AStreamDestroy( stream_t *s );
static void UStreamDestroy( stream_t *s );
static int ASeek( stream_t *s, int64_t i_pos );
+static int ARecordSetState( stream_t *s, bool b_record, const char *psz_extension );
+static void ARecordWrite( stream_t *s, const uint8_t *p_buffer, size_t i_buffer );
/****************************************************************************
* Method 3 helpers:
else
p_sys->method = Stream;
+ p_sys->record.b_active = false;
+
p_sys->i_pos = p_access->info.i_pos;
/* Stats */
vlc_object_detach( s );
- if( p_sys->method == Block ) block_ChainRelease( p_sys->block.p_first );
- else if ( p_sys->method == Immediate ) free( p_sys->immediate.p_buffer );
- else free( p_sys->stream.p_buffer );
+ if( p_sys->record.b_active )
+ ARecordSetState( s, false, NULL );
+
+ if( p_sys->method == Block )
+ block_ChainRelease( p_sys->block.p_first );
+ else if ( p_sys->method == Immediate )
+ free( p_sys->immediate.p_buffer );
+ else
+ free( p_sys->stream.p_buffer );
free( p_sys->p_peek );
access_t *p_access = p_sys->p_access;
bool *p_bool;
+ bool b_bool;
+ const char *psz_string;
int64_t *pi_64, i_64;
int i_int;
case STREAM_GET_CONTENT_TYPE:
return access_Control( p_access, ACCESS_GET_CONTENT_TYPE,
va_arg( args, char ** ) );
+ case STREAM_SET_RECORD_STATE:
+ b_bool = (bool)va_arg( args, int );
+ psz_string = NULL;
+ if( b_bool )
+ psz_string = (const char*)va_arg( args, const char* );
+ return ARecordSetState( s, b_bool, psz_string );
default:
msg_Err( s, "invalid stream_vaControl query=0x%x", i_query );
return VLC_SUCCESS;
}
+/****************************************************************************
+ * ARecord*: record stream functions
+ ****************************************************************************/
+
+/* TODO FIXME nearly the same logic that snapshot code */
+static char *ARecordGetFileName( stream_t *s, const char *psz_path, const char *psz_prefix, const char *psz_extension )
+{
+ char *psz_file;
+ DIR *path;
+
+ path = utf8_opendir( psz_path );
+ if( path )
+ {
+ closedir( path );
+
+ const char *psz_prefix = "vlc-record-%Y-%m-%d-%H:%M:%S-$p"; // TODO allow conf ?
+ char *psz_tmp = str_format( s, psz_prefix );
+ if( !psz_tmp )
+ return NULL;
+
+ filename_sanitize( psz_tmp );
+ if( asprintf( &psz_file, "%s"DIR_SEP"%s.%s",
+ psz_path, psz_tmp, psz_extension ) < 0 )
+ psz_file = NULL;
+ free( psz_tmp );
+ return psz_file;
+ }
+ else
+ {
+ psz_file = str_format( s, psz_path );
+ path_sanitize( psz_file );
+ return psz_file;
+ }
+}
+
+static int ARecordStart( stream_t *s, const char *psz_extension )
+{
+ stream_sys_t *p_sys = s->p_sys;
+
+ DIR *path;
+ char *psz_file;
+ FILE *f;
+
+ /* */
+ if( !psz_extension )
+ psz_extension = "dat";
+
+ /* Retreive path */
+ char *psz_path = var_CreateGetString( s, "input-record-path" );
+ if( !psz_path || *psz_path == '\0' )
+ {
+ free( psz_path );
+ psz_path = strdup( config_GetHomeDir() );
+ }
+
+ if( !psz_path )
+ return VLC_ENOMEM;
+
+ /* Create file name
+ * TODO allow prefix configuration */
+ psz_file = ARecordGetFileName( s, psz_path, "vlc-record-%Y-%m-%d-%H:%M:%S-$p", psz_extension );
+
+ free( psz_path );
+
+ if( !psz_file )
+ return VLC_ENOMEM;
+
+ f = utf8_fopen( psz_file, "wb" );
+ if( !f )
+ {
+ free( psz_file );
+ return VLC_EGENERIC;
+ }
+ msg_Dbg( s, "Recording into %s", psz_file );
+ free( psz_file );
+
+ /* */
+ p_sys->record.f = f;
+ p_sys->record.b_active = true;
+ return VLC_SUCCESS;
+}
+static int ARecordStop( stream_t *s )
+{
+ stream_sys_t *p_sys = s->p_sys;
+
+ assert( p_sys->record.b_active );
+ msg_Dbg( s, "Recording completed" );
+ fclose( p_sys->record.f );
+ p_sys->record.b_active = false;
+ return VLC_SUCCESS;
+}
+
+static int ARecordSetState( stream_t *s, bool b_record, const char *psz_extension )
+{
+ stream_sys_t *p_sys = s->p_sys;
+
+ if( !!p_sys->record.b_active == !!b_record )
+ return VLC_SUCCESS;
+
+ if( b_record )
+ return ARecordStart( s, psz_extension );
+ else
+ return ARecordStop( s );
+}
+static void ARecordWrite( stream_t *s, const uint8_t *p_buffer, size_t i_buffer )
+{
+ stream_sys_t *p_sys = s->p_sys;
+
+ assert( p_sys->record.b_active );
+
+ if( i_buffer )
+ fwrite( p_buffer, 1, i_buffer, p_sys->record.f );
+}
/****************************************************************************
* Method 1:
}
}
+ if( p_sys->record.b_active && i_data > 0 )
+ ARecordWrite( s, p_read, i_data );
+
p_sys->i_pos += i_data;
return i_data;
}
}
}
+ if( p_sys->record.b_active && i_data > 0 )
+ ARecordWrite( s, p_read, i_data );
+
return i_data;
}
}
}
+ if( p_sys->record.b_active && i_copy > 0 )
+ ARecordWrite( s, p_read, i_copy );
+
p_sys->i_pos += i_to_read;
return i_to_read + i_copy;
static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
+static int RecordCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void *p_data );
+
typedef struct
{
const char *psz_name;
CALLBACK( "video-es", ESCallback ),
CALLBACK( "audio-es", ESCallback ),
CALLBACK( "spu-es", ESCallback ),
+ CALLBACK( "record", RecordCallback ),
CALLBACK( NULL, NULL )
};
val.i_time = 0;
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
- p_input->p->pts_adjust.auto_adjust = var_CreateGetBool(
- p_input, "auto-adjust-pts-delay" );
-
/* Video ES */
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
text.psz_string = _("Video Track");
*****************************************************************************/
void input_ConfigVarInit ( input_thread_t *p_input )
{
- vlc_value_t val;
-
/* Create Object Variables for private use only */
if( !p_input->b_preparsing )
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_input, "clock-synchro",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
+ var_Create( p_input, "auto-adjust-pts-delay",
+ VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
}
var_Create( p_input, "seekable", VLC_VAR_BOOL );
- val.b_bool = true; /* Fixed later*/
- var_Change( p_input, "seekable", VLC_VAR_SETVALUE, &val, NULL );
+ var_SetBool( p_input, "seekable", true ); /* Fixed later*/
+
var_Create( p_input, "can-pause", VLC_VAR_BOOL );
- val.b_bool = true; /* Fixed later*/
- var_Change( p_input, "can-pause", VLC_VAR_SETVALUE, &val, NULL );
+ var_SetBool( p_input, "can-pause", true ); /* Fixed later*/
+
+ var_Create( p_input, "can-record", VLC_VAR_BOOL );
+ var_SetBool( p_input, "can-record", false ); /* Fixed later*/
+
+ var_Create( p_input, "record", VLC_VAR_BOOL );
+ var_SetBool( p_input, "record", false );
+
var_Create( p_input, "teletext-es", VLC_VAR_INTEGER );
var_SetInteger( p_input, "teletext-es", -1 );
return VLC_SUCCESS;
}
+
+static int RecordCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t*)p_this;
+ VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data);
+
+ input_ControlPush( p_input, INPUT_CONTROL_SET_RECORD_STATE, &newval );
+
+ return VLC_SUCCESS;
+}
"the form \"{name=bookmark-name,time=optional-time-offset," \
"bytes=optional-byte-offset},{...}\"")
+#define INPUT_RECORD_PATH_TEXT N_("Record directory or filename")
+#define INPUT_RECORD_PATH_LONGTEXT N_( \
+ "Directory or filename where the records will be stored" )
+
// DEPRECATED
#define SUB_CAT_LONGTEXT N_( \
"These options allow you to modify the behavior of the subpictures " \
add_bool( "network-synchronisation", false, NULL, NETSYNC_TEXT,
NETSYNC_LONGTEXT, true );
+ add_string( "input-record-path", NULL, NULL, INPUT_RECORD_PATH_TEXT,
+ INPUT_RECORD_PATH_LONGTEXT, true );
+
/* Decoder options */
add_category_hint( N_("Decoders"), CODEC_CAT_LONGTEXT , true );
add_string( "codec", NULL, NULL, CODEC_TEXT,