1 /*****************************************************************************
2 * var.c: object variables for input thread
3 *****************************************************************************
4 * Copyright (C) 2004-2007 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_memstream.h>
38 #include "input_internal.h"
40 /*****************************************************************************
42 *****************************************************************************/
43 static int StateCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
44 vlc_value_t oldval
, vlc_value_t newval
, void * );
45 static int RateCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
46 vlc_value_t oldval
, vlc_value_t newval
, void * );
47 static int PositionCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
48 vlc_value_t oldval
, vlc_value_t newval
, void * );
49 static int TimeCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
50 vlc_value_t oldval
, vlc_value_t newval
, void * );
51 static int TimeOffsetCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
52 vlc_value_t oldval
, vlc_value_t newval
, void * );
53 static int ProgramCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
54 vlc_value_t oldval
, vlc_value_t newval
, void * );
55 static int TitleCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
56 vlc_value_t oldval
, vlc_value_t newval
, void * );
57 static int SeekpointCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
58 vlc_value_t oldval
, vlc_value_t newval
, void * );
59 static int NavigationCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
60 vlc_value_t oldval
, vlc_value_t newval
, void * );
61 static int EsVideoCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
62 vlc_value_t oldval
, vlc_value_t newval
, void * );
63 static int EsAudioCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
64 vlc_value_t oldval
, vlc_value_t newval
, void * );
65 static int EsSpuCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
66 vlc_value_t oldval
, vlc_value_t newval
, void * );
67 static int EsDelayCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
68 vlc_value_t oldval
, vlc_value_t newval
, void * );
70 static int BookmarkCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
71 vlc_value_t oldval
, vlc_value_t newval
, void * );
73 static int RecordCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
74 vlc_value_t oldval
, vlc_value_t newval
,
76 static int FrameNextCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
77 vlc_value_t oldval
, vlc_value_t newval
,
79 static void input_LegacyVarTitle( input_thread_t
*p_input
, int i_title
);
80 static void input_LegacyVarNavigation( input_thread_t
*p_input
);
85 vlc_callback_t callback
;
86 } vlc_input_callback_t
;
88 static void InputAddCallbacks( input_thread_t
*, const vlc_input_callback_t
* );
89 static void InputDelCallbacks( input_thread_t
*, const vlc_input_callback_t
* );
91 #ifdef CALLBACK /* For windows */
92 # undef CALLBACK /* We don't care of this one here */
94 /* List all callbacks added by input */
95 #define CALLBACK(name,cb) { name, cb }
96 static const vlc_input_callback_t p_input_callbacks
[] =
98 CALLBACK( "state", StateCallback
),
99 CALLBACK( "rate", RateCallback
),
100 CALLBACK( "position", PositionCallback
),
101 CALLBACK( "time", TimeCallback
),
102 CALLBACK( "time-offset", TimeOffsetCallback
),
103 CALLBACK( "bookmark", BookmarkCallback
),
104 CALLBACK( "program", ProgramCallback
),
105 CALLBACK( "title", TitleCallback
),
106 CALLBACK( "chapter", SeekpointCallback
),
107 CALLBACK( "audio-delay", EsDelayCallback
),
108 CALLBACK( "spu-delay", EsDelayCallback
),
109 CALLBACK( "video-es", EsVideoCallback
),
110 CALLBACK( "audio-es", EsAudioCallback
),
111 CALLBACK( "spu-es", EsSpuCallback
),
112 CALLBACK( "record", RecordCallback
),
113 CALLBACK( "frame-next", FrameNextCallback
),
115 CALLBACK( NULL
, NULL
)
119 static void Trigger( input_thread_t
*p_input
, int i_type
)
121 var_SetInteger( p_input
, "intf-event", i_type
);
123 static void VarListAdd( input_thread_t
*p_input
,
124 const char *psz_variable
, int i_event
,
125 int i_value
, const char *psz_text
)
131 var_Change( p_input
, psz_variable
, VLC_VAR_ADDCHOICE
, val
, psz_text
);
133 Trigger( p_input
, i_event
);
135 static void VarListDel( input_thread_t
*p_input
,
136 const char *psz_variable
, int i_event
,
144 var_Change( p_input
, psz_variable
, VLC_VAR_DELCHOICE
, val
);
148 var_Change( p_input
, psz_variable
, VLC_VAR_CLEARCHOICES
);
151 Trigger( p_input
, i_event
);
153 static void VarListSelect( input_thread_t
*p_input
,
154 const char *psz_variable
, int i_event
,
160 var_Change( p_input
, psz_variable
, VLC_VAR_SETVALUE
, val
);
162 Trigger( p_input
, i_event
);
164 static const char *GetEsVarName( enum es_format_category_e i_cat
)
179 static void UpdateBookmarksOption( input_thread_t
*p_input
)
181 input_thread_private_t
*priv
= input_priv(p_input
);
182 struct vlc_memstream vstr
;
184 vlc_memstream_open( &vstr
);
185 vlc_memstream_puts( &vstr
, "bookmarks=" );
187 vlc_mutex_lock( &priv
->p_item
->lock
);
188 var_Change( p_input
, "bookmark", VLC_VAR_CLEARCHOICES
);
190 for( int i
= 0; i
< priv
->i_bookmark
; i
++ )
192 seekpoint_t
const* sp
= priv
->pp_bookmark
[i
];
194 /* Add bookmark to choice-list */
195 var_Change( p_input
, "bookmark", VLC_VAR_ADDCHOICE
,
196 (vlc_value_t
){ .i_int
= i
}, sp
->psz_name
);
198 /* Append bookmark to option-buffer */
199 /* TODO: escape inappropriate values */
200 vlc_memstream_printf( &vstr
, "%s{name=%s,time=%.3f}",
201 i
> 0 ? "," : "", sp
->psz_name
, ( 1. * sp
->i_time_offset
) / CLOCK_FREQ
);
204 vlc_mutex_unlock( &priv
->p_item
->lock
);
206 if( vlc_memstream_close( &vstr
) == VLC_SUCCESS
)
208 bool b_overwritten
= false;
210 for( int i
= 0; i
< priv
->p_item
->i_options
; ++i
)
212 char** ppsz_option
= &priv
->p_item
->ppsz_options
[i
];
214 if( strncmp( *ppsz_option
, "bookmarks=", 10 ) == 0 )
216 free( *ppsz_option
);
217 *ppsz_option
= vstr
.ptr
;
218 b_overwritten
= true;
224 input_item_AddOption( priv
->p_item
, vstr
.ptr
,
225 VLC_INPUT_OPTION_UNIQUE
);
231 void input_LegacyEvents( input_thread_t
*p_input
, void *user_data
,
232 const struct vlc_input_event
*event
)
237 switch( event
->type
)
239 case INPUT_EVENT_STATE
:
240 val
.i_int
= event
->state
;
241 var_Change( p_input
, "state", VLC_VAR_SETVALUE
, val
);
243 case INPUT_EVENT_DEAD
:
245 case INPUT_EVENT_RATE
:
246 val
.f_float
= event
->rate
;
247 var_Change( p_input
, "rate", VLC_VAR_SETVALUE
, val
);
249 case INPUT_EVENT_CAPABILITIES
:
250 var_SetBool( p_input
, "can-seek",
251 event
->capabilities
& VLC_INPUT_CAPABILITIES_SEEKABLE
);
252 var_SetBool( p_input
, "can-pause",
253 event
->capabilities
& VLC_INPUT_CAPABILITIES_PAUSEABLE
);
254 var_SetBool( p_input
, "can-rate",
255 event
->capabilities
& VLC_INPUT_CAPABILITIES_CHANGE_RATE
);
256 var_SetBool( p_input
, "can-rewind",
257 event
->capabilities
& VLC_INPUT_CAPABILITIES_REWINDABLE
);
258 var_SetBool( p_input
, "can-record",
259 event
->capabilities
& VLC_INPUT_CAPABILITIES_RECORDABLE
);
261 case INPUT_EVENT_POSITION
:
262 val
.f_float
= event
->position
.percentage
;
263 var_Change( p_input
, "position", VLC_VAR_SETVALUE
, val
);
264 val
.i_int
= event
->position
.ms
;
265 var_Change( p_input
, "time", VLC_VAR_SETVALUE
, val
);
267 case INPUT_EVENT_LENGTH
:
268 /* FIXME ugly + what about meta change event ? */
269 if( var_GetInteger( p_input
, "length" ) == event
->length
)
271 val
.i_int
= event
->length
;
272 var_Change( p_input
, "length", VLC_VAR_SETVALUE
, val
);
274 case INPUT_EVENT_TITLE
:
275 val
.i_int
= event
->title
;
276 var_Change( p_input
, "title", VLC_VAR_SETVALUE
, val
);
277 input_LegacyVarNavigation( p_input
);
278 input_LegacyVarTitle( p_input
, event
->title
);
280 case INPUT_EVENT_CHAPTER
:
282 val
.i_int
= event
->chapter
.seekpoint
;
283 var_Change( p_input
, "chapter", VLC_VAR_SETVALUE
, val
);
286 char psz_title
[sizeof ("title ") + 3 * sizeof (int)];
287 sprintf( psz_title
, "title %2u", event
->chapter
.title
);
288 var_Change( p_input
, psz_title
, VLC_VAR_SETVALUE
, val
);
290 case INPUT_EVENT_PROGRAM
:
291 switch (event
->program
.action
)
293 case VLC_INPUT_PROGRAM_ADDED
:
294 VarListAdd( p_input
, "program", INPUT_EVENT_PROGRAM
,
295 event
->program
.id
, event
->program
.title
);
297 case VLC_INPUT_PROGRAM_DELETED
:
298 VarListDel( p_input
, "program", INPUT_EVENT_PROGRAM
,
301 case VLC_INPUT_PROGRAM_SELECTED
:
302 VarListSelect( p_input
, "program", INPUT_EVENT_PROGRAM
,
305 case VLC_INPUT_PROGRAM_SCRAMBLED
:
306 if( var_GetInteger( p_input
, "program" ) != event
->program
.id
)
308 var_SetBool( p_input
, "program-scrambled", event
->program
.scrambled
);
313 switch (event
->es
.action
)
315 case VLC_INPUT_ES_ADDED
:
317 const char *varname
= GetEsVarName( event
->es
.cat
);
319 VarListAdd( p_input
, varname
, INPUT_EVENT_ES
,
320 event
->es
.id
, event
->es
.title
);
323 case VLC_INPUT_ES_DELETED
:
325 const char *varname
= GetEsVarName( event
->es
.cat
);
327 VarListDel( p_input
, varname
, INPUT_EVENT_ES
,
331 case VLC_INPUT_ES_SELECTED
:
333 const char *varname
= GetEsVarName( event
->es
.cat
);
335 VarListSelect( p_input
, varname
, INPUT_EVENT_ES
,
341 case INPUT_EVENT_TELETEXT
:
342 switch (event
->teletext
.action
)
344 case VLC_INPUT_TELETEXT_ADDED
:
345 VarListAdd( p_input
, "teletext-es", INPUT_EVENT_TELETEXT
,
346 event
->teletext
.id
, event
->teletext
.title
);
348 case VLC_INPUT_TELETEXT_DELETED
:
349 VarListDel( p_input
, "teletext-es", INPUT_EVENT_TELETEXT
,
350 event
->teletext
.id
);
352 case VLC_INPUT_TELETEXT_SELECTED
:
353 VarListSelect( p_input
, "teletext-es", INPUT_EVENT_TELETEXT
,
354 event
->teletext
.id
);
358 case INPUT_EVENT_RECORD
:
359 val
.b_bool
= event
->record
;
360 var_Change( p_input
, "record", VLC_VAR_SETVALUE
, val
);
362 case INPUT_EVENT_ITEM_META
:
364 case INPUT_EVENT_ITEM_INFO
:
366 case INPUT_EVENT_ITEM_EPG
:
368 case INPUT_EVENT_STATISTICS
:
370 case INPUT_EVENT_SIGNAL
:
371 val
.f_float
= event
->signal
.quality
;
372 var_Change( p_input
, "signal-quality", VLC_VAR_SETVALUE
, val
);
373 val
.f_float
= event
->signal
.strength
;
374 var_Change( p_input
, "signal-strength", VLC_VAR_SETVALUE
, val
);
376 case INPUT_EVENT_AUDIO_DELAY
:
377 val
.i_int
= event
->audio_delay
;
378 var_Change( p_input
, "audio-delay", VLC_VAR_SETVALUE
, val
);
380 case INPUT_EVENT_SUBTITLE_DELAY
:
381 val
.i_int
= event
->subtitle_delay
;
382 var_Change( p_input
, "spu-delay", VLC_VAR_SETVALUE
, val
);
384 case INPUT_EVENT_BOOKMARK
:
385 UpdateBookmarksOption( p_input
);
387 case INPUT_EVENT_CACHE
:
388 val
.f_float
= event
->cache
;
389 var_Change( p_input
, "cache", VLC_VAR_SETVALUE
, val
);
391 case INPUT_EVENT_AOUT
:
393 case INPUT_EVENT_VOUT
:
396 Trigger( p_input
, event
->type
);
399 /*****************************************************************************
400 * input_LegacyVarInit:
401 * Create all control object variables with their callbacks
402 *****************************************************************************/
403 void input_LegacyVarInit ( input_thread_t
*p_input
)
407 var_Create( p_input
, "can-seek", VLC_VAR_BOOL
);
408 var_SetBool( p_input
, "can-seek", true ); /* Fixed later*/
410 var_Create( p_input
, "can-pause", VLC_VAR_BOOL
);
411 var_SetBool( p_input
, "can-pause", true ); /* Fixed later*/
413 var_Create( p_input
, "can-rate", VLC_VAR_BOOL
);
414 var_SetBool( p_input
, "can-rate", false );
416 var_Create( p_input
, "can-rewind", VLC_VAR_BOOL
);
417 var_SetBool( p_input
, "can-rewind", false );
419 var_Create( p_input
, "can-record", VLC_VAR_BOOL
);
420 var_SetBool( p_input
, "can-record", false ); /* Fixed later*/
422 var_Create( p_input
, "record", VLC_VAR_BOOL
);
423 var_SetBool( p_input
, "record", false );
425 var_Create( p_input
, "teletext-es", VLC_VAR_INTEGER
);
426 var_SetInteger( p_input
, "teletext-es", -1 );
428 var_Create( p_input
, "cache", VLC_VAR_FLOAT
);
429 var_SetFloat( p_input
, "cache", 0.0 );
431 var_Create( p_input
, "signal-quality", VLC_VAR_FLOAT
);
432 var_SetFloat( p_input
, "signal-quality", -1 );
434 var_Create( p_input
, "signal-strength", VLC_VAR_FLOAT
);
435 var_SetFloat( p_input
, "signal-strength", -1 );
437 var_Create( p_input
, "program-scrambled", VLC_VAR_BOOL
);
438 var_SetBool( p_input
, "program-scrambled", false );
441 var_Create( p_input
, "state", VLC_VAR_INTEGER
);
442 val
.i_int
= input_priv(p_input
)->i_state
;
443 var_Change( p_input
, "state", VLC_VAR_SETVALUE
, val
);
446 var_Create( p_input
, "rate", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
448 var_Create( p_input
, "frame-next", VLC_VAR_VOID
);
451 var_Create( p_input
, "position", VLC_VAR_FLOAT
);
454 var_Create( p_input
, "time", VLC_VAR_INTEGER
);
455 var_Create( p_input
, "time-offset", VLC_VAR_INTEGER
); /* relative */
458 var_Create( p_input
, "bookmark", VLC_VAR_INTEGER
| VLC_VAR_ISCOMMAND
);
459 var_Change( p_input
, "bookmark", VLC_VAR_SETTEXT
, _("Bookmark") );
462 var_Create( p_input
, "program", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
463 var_Get( p_input
, "program", &val
);
465 var_Change( p_input
, "program", VLC_VAR_DELCHOICE
, val
);
466 var_Change( p_input
, "program", VLC_VAR_SETTEXT
, _("Program") );
469 var_Create( p_input
, "programs", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
470 var_Change( p_input
, "programs", VLC_VAR_SETTEXT
, _("Programs") );
473 var_Create( p_input
, "title", VLC_VAR_INTEGER
);
474 var_Change( p_input
, "title", VLC_VAR_SETTEXT
, _("Title") );
477 var_Create( p_input
, "chapter", VLC_VAR_INTEGER
);
478 var_Change( p_input
, "chapter", VLC_VAR_SETTEXT
, _("Chapter") );
481 var_Create( p_input
, "audio-delay", VLC_VAR_INTEGER
);
482 var_SetInteger( p_input
, "audio-delay",
483 VLC_TICK_FROM_MS( var_GetInteger( p_input
, "audio-desync" ) ) );
484 var_Create( p_input
, "spu-delay", VLC_VAR_INTEGER
);
488 var_Create( p_input
, "video-es", VLC_VAR_INTEGER
);
489 var_Change( p_input
, "video-es", VLC_VAR_SETVALUE
, val
);
490 var_Change( p_input
, "video-es", VLC_VAR_SETTEXT
, _("Video Track") );
493 var_Create( p_input
, "audio-es", VLC_VAR_INTEGER
);
494 var_Change( p_input
, "audio-es", VLC_VAR_SETVALUE
, val
);
495 var_Change( p_input
, "audio-es", VLC_VAR_SETTEXT
, _("Audio Track") );
498 var_Create( p_input
, "spu-es", VLC_VAR_INTEGER
);
499 var_Change( p_input
, "spu-es", VLC_VAR_SETVALUE
, val
);
500 var_Change( p_input
, "spu-es", VLC_VAR_SETTEXT
, _("Subtitle Track") );
502 var_Create( p_input
, "spu-choice", VLC_VAR_INTEGER
);
503 var_SetInteger( p_input
, "spu-choice", -1 );
505 /* Special read only objects variables for intf */
506 var_Create( p_input
, "bookmarks", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
508 var_Create( p_input
, "length", VLC_VAR_INTEGER
);
510 var_Create( p_input
, "bit-rate", VLC_VAR_INTEGER
);
511 var_Create( p_input
, "sample-rate", VLC_VAR_INTEGER
);
513 /* Special "intf-event" variable. */
514 var_Create( p_input
, "intf-event", VLC_VAR_INTEGER
);
517 * XXX we put callback only in non preparsing mode. We need to create the variable
518 * unless someone want to check all var_Get/var_Change return value ... */
519 if( !input_priv(p_input
)->b_preparsing
)
520 InputAddCallbacks( p_input
, p_input_callbacks
);
523 /*****************************************************************************
524 * input_LegacyVarNavigation:
525 * Create all remaining control object variables
526 *****************************************************************************/
527 static void input_LegacyVarNavigation( input_thread_t
*p_input
)
529 /* Create more command variables */
530 if( input_priv(p_input
)->i_title
> 1 )
532 if( var_Type( p_input
, "next-title" ) == 0 ) {
533 var_Create( p_input
, "next-title", VLC_VAR_VOID
);
534 var_Change( p_input
, "next-title", VLC_VAR_SETTEXT
,
536 var_AddCallback( p_input
, "next-title", TitleCallback
, NULL
);
539 if( var_Type( p_input
, "prev-title" ) == 0 ) {
540 var_Create( p_input
, "prev-title", VLC_VAR_VOID
);
541 var_Change( p_input
, "prev-title", VLC_VAR_SETTEXT
,
542 _("Previous title") );
543 var_AddCallback( p_input
, "prev-title", TitleCallback
, NULL
);
546 if( var_Type( p_input
, "menu-title" ) == 0 ) {
547 var_Create( p_input
, "menu-title", VLC_VAR_VOID
);
548 var_Change( p_input
, "menu-title", VLC_VAR_SETTEXT
,
550 var_AddCallback( p_input
, "menu-title", TitleCallback
, NULL
);
553 if( var_Type( p_input
, "menu-popup" ) == 0 ) {
554 var_Create( p_input
, "menu-popup", VLC_VAR_VOID
);
555 var_Change( p_input
, "menu-popup", VLC_VAR_SETTEXT
,
557 var_AddCallback( p_input
, "menu-popup", TitleCallback
, NULL
);
561 /* Create titles and chapters */
562 var_Change( p_input
, "title", VLC_VAR_CLEARCHOICES
);
564 for( int i
= 0; i
< input_priv(p_input
)->i_title
; i
++ )
566 vlc_value_t val2
, text2
;
567 char title
[sizeof("title ") + 3 * sizeof (int)];
569 /* Add Navigation entries */
570 sprintf( title
, "title %2u", i
);
571 var_Destroy( p_input
, title
);
572 var_Create( p_input
, title
, VLC_VAR_INTEGER
| VLC_VAR_ISCOMMAND
);
573 var_AddCallback( p_input
, title
,
574 NavigationCallback
, (void *)(intptr_t)i
);
576 char psz_length
[MSTRTIME_MAX_SIZE
+ sizeof(" []")];
577 if( input_priv(p_input
)->title
[i
]->i_length
> 0 )
579 strcpy( psz_length
, " [" );
580 secstotimestr( &psz_length
[2], SEC_FROM_VLC_TICK(input_priv(p_input
)->title
[i
]->i_length
) );
581 strcat( psz_length
, "]" );
584 psz_length
[0] = '\0';
587 if( input_priv(p_input
)->title
[i
]->psz_name
== NULL
||
588 *input_priv(p_input
)->title
[i
]->psz_name
== '\0' )
590 if( asprintf( &titlestr
, _("Title %i%s"),
591 i
+ input_priv(p_input
)->i_title_offset
, psz_length
) == -1 )
596 if( asprintf( &titlestr
, "%s%s",
597 input_priv(p_input
)->title
[i
]->psz_name
, psz_length
) == -1 )
601 /* Add title choice */
603 var_Change( p_input
, "title", VLC_VAR_ADDCHOICE
, val2
,
604 (const char *)titlestr
);
608 for( int j
= 0; j
< input_priv(p_input
)->title
[i
]->i_seekpoint
; j
++ )
612 if( input_priv(p_input
)->title
[i
]->seekpoint
[j
]->psz_name
== NULL
||
613 *input_priv(p_input
)->title
[i
]->seekpoint
[j
]->psz_name
== '\0' )
616 if( asprintf( &text2
.psz_string
, _("Chapter %i"),
617 j
+ input_priv(p_input
)->i_seekpoint_offset
) == -1 )
623 strdup( input_priv(p_input
)->title
[i
]->seekpoint
[j
]->psz_name
);
626 var_Change( p_input
, title
, VLC_VAR_ADDCHOICE
, val2
,
627 (const char *)text2
.psz_string
);
628 free( text2
.psz_string
);
634 /*****************************************************************************
635 * input_LegacyVarTitle:
636 * Create all variables for a title
637 *****************************************************************************/
638 static void input_LegacyVarTitle( input_thread_t
*p_input
, int i_title
)
640 const input_title_t
*t
= input_priv(p_input
)->title
[i_title
];
644 /* Create/Destroy command variables */
645 if( t
->i_seekpoint
<= 1 )
647 var_Destroy( p_input
, "next-chapter" );
648 var_Destroy( p_input
, "prev-chapter" );
650 else if( var_Type( p_input
, "next-chapter" ) == 0 )
652 var_Create( p_input
, "next-chapter", VLC_VAR_VOID
);
653 var_Change( p_input
, "next-chapter", VLC_VAR_SETTEXT
,
655 var_AddCallback( p_input
, "next-chapter", SeekpointCallback
, NULL
);
657 var_Create( p_input
, "prev-chapter", VLC_VAR_VOID
);
658 var_Change( p_input
, "prev-chapter", VLC_VAR_SETTEXT
,
659 _("Previous chapter") );
660 var_AddCallback( p_input
, "prev-chapter", SeekpointCallback
, NULL
);
663 /* Build chapter list */
664 var_Change( p_input
, "chapter", VLC_VAR_CLEARCHOICES
);
665 for( i
= 0; i
< t
->i_seekpoint
; i
++ )
670 if( t
->seekpoint
[i
]->psz_name
== NULL
||
671 *t
->seekpoint
[i
]->psz_name
== '\0' )
674 if( asprintf( &text
.psz_string
, _("Chapter %i"),
675 i
+ input_priv(p_input
)->i_seekpoint_offset
) == -1 )
680 text
.psz_string
= strdup( t
->seekpoint
[i
]->psz_name
);
683 var_Change( p_input
, "chapter", VLC_VAR_ADDCHOICE
, val
,
684 (const char *)text
.psz_string
);
685 free( text
.psz_string
);
689 /*****************************************************************************
690 * input_ConfigVarInit:
691 * Create all config object variables
692 *****************************************************************************/
693 void input_ConfigVarInit ( input_thread_t
*p_input
)
695 /* Create Object Variables for private use only */
697 if( !input_priv(p_input
)->b_preparsing
)
699 var_Create( p_input
, "video", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
700 var_Create( p_input
, "audio", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
701 var_Create( p_input
, "spu", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
703 var_Create( p_input
, "audio-track", VLC_VAR_INTEGER
|VLC_VAR_DOINHERIT
);
704 var_Create( p_input
, "sub-track", VLC_VAR_INTEGER
|VLC_VAR_DOINHERIT
);
706 var_Create( p_input
, "audio-language",
707 VLC_VAR_STRING
|VLC_VAR_DOINHERIT
);
708 var_Create( p_input
, "sub-language",
709 VLC_VAR_STRING
|VLC_VAR_DOINHERIT
);
710 var_Create( p_input
, "menu-language",
711 VLC_VAR_STRING
|VLC_VAR_DOINHERIT
);
713 var_Create( p_input
, "audio-track-id",
714 VLC_VAR_INTEGER
|VLC_VAR_DOINHERIT
);
715 var_Create( p_input
, "sub-track-id",
716 VLC_VAR_INTEGER
|VLC_VAR_DOINHERIT
);
718 var_Create( p_input
, "sub-file", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
719 var_Create( p_input
, "sub-autodetect-file", VLC_VAR_BOOL
|
721 var_Create( p_input
, "sub-autodetect-path", VLC_VAR_STRING
|
723 var_Create( p_input
, "sub-autodetect-fuzzy", VLC_VAR_INTEGER
|
726 var_Create( p_input
, "sout", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
727 var_Create( p_input
, "sout-all", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
728 var_Create( p_input
, "sout-audio", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
729 var_Create( p_input
, "sout-video", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
730 var_Create( p_input
, "sout-spu", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
731 var_Create( p_input
, "sout-keep", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
733 var_Create( p_input
, "input-repeat",
734 VLC_VAR_INTEGER
|VLC_VAR_DOINHERIT
);
735 var_Create( p_input
, "start-time", VLC_VAR_FLOAT
|VLC_VAR_DOINHERIT
);
736 var_Create( p_input
, "stop-time", VLC_VAR_FLOAT
|VLC_VAR_DOINHERIT
);
737 var_Create( p_input
, "run-time", VLC_VAR_FLOAT
|VLC_VAR_DOINHERIT
);
738 var_Create( p_input
, "input-fast-seek", VLC_VAR_BOOL
|VLC_VAR_DOINHERIT
);
740 var_Create( p_input
, "input-slave",
741 VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
743 var_Create( p_input
, "audio-desync",
744 VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
745 var_Create( p_input
, "cr-average",
746 VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
747 var_Create( p_input
, "clock-synchro",
748 VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
752 var_Create( p_input
, "input-record-native", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
755 var_Create( p_input
, "access", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
756 var_Create( p_input
, "demux", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
757 var_Create( p_input
, "demux-filter", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
758 var_Create( p_input
, "stream-filter", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
761 var_Create( p_input
, "meta-title", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
762 var_Create( p_input
, "meta-author", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
763 var_Create( p_input
, "meta-artist", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
764 var_Create( p_input
, "meta-genre", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
765 var_Create( p_input
, "meta-copyright", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
766 var_Create( p_input
, "meta-description", VLC_VAR_STRING
|VLC_VAR_DOINHERIT
);
767 var_Create( p_input
, "meta-date", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
768 var_Create( p_input
, "meta-url", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
771 /*****************************************************************************
772 * Callbacks managements:
773 *****************************************************************************/
774 static void InputAddCallbacks( input_thread_t
*p_input
,
775 const vlc_input_callback_t
*p_callbacks
)
778 for( i
= 0; p_callbacks
[i
].psz_name
!= NULL
; i
++ )
779 var_AddCallback( p_input
,
780 p_callbacks
[i
].psz_name
,
781 p_callbacks
[i
].callback
, NULL
);
784 static void InputDelCallbacks( input_thread_t
*p_input
,
785 const vlc_input_callback_t
*p_callbacks
)
788 for( i
= 0; p_callbacks
[i
].psz_name
!= NULL
; i
++ )
789 var_DelCallback( p_input
,
790 p_callbacks
[i
].psz_name
,
791 p_callbacks
[i
].callback
, NULL
);
794 /*****************************************************************************
796 *****************************************************************************/
797 static int StateCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
798 vlc_value_t oldval
, vlc_value_t newval
,
801 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
802 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
804 if( newval
.i_int
== PLAYING_S
|| newval
.i_int
== PAUSE_S
)
806 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_STATE
, &newval
);
813 static int RateCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
814 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
816 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
817 VLC_UNUSED(oldval
); VLC_UNUSED(p_data
); VLC_UNUSED(psz_cmd
);
819 newval
.i_int
= INPUT_RATE_DEFAULT
/ newval
.f_float
;
820 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_RATE
, &newval
);
825 static int PositionCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
826 vlc_value_t oldval
, vlc_value_t newval
,
829 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
831 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
833 /* Update "length" for better intf behaviour */
834 const vlc_tick_t i_length
= var_GetInteger( p_input
, "length" );
835 if( i_length
> 0 && newval
.f_float
>= 0.f
&& newval
.f_float
<= 1.f
)
839 val
.i_int
= i_length
* newval
.f_float
;
840 var_Change( p_input
, "time", VLC_VAR_SETVALUE
, val
);
843 input_SetPosition( p_input
, newval
.f_float
,
844 var_GetBool( p_input
, "input-fast-seek" ) );
848 static int TimeCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
849 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
851 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
852 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
854 /* Update "position" for better intf behaviour */
855 const int64_t i_length
= var_GetInteger( p_input
, "length" );
856 if( i_length
> 0 && newval
.i_int
>= 0 && newval
.i_int
<= i_length
)
860 val
.f_float
= (double)newval
.i_int
/(double)i_length
;
861 var_Change( p_input
, "position", VLC_VAR_SETVALUE
, val
);
863 * Notify the intf that a new event has been occurred.
864 * XXX this is a bit hackish but it's the only way to do it now.
866 var_SetInteger( p_input
, "intf-event", INPUT_EVENT_POSITION
);
869 input_SetTime( p_input
, newval
.i_int
,
870 var_GetBool( p_input
, "input-fast-seek" ) );
874 static int TimeOffsetCallback( vlc_object_t
*obj
, char const *varname
,
875 vlc_value_t prev
, vlc_value_t cur
, void *data
)
877 VLC_UNUSED(varname
); VLC_UNUSED(prev
); VLC_UNUSED(data
);
879 int64_t i_time
= var_GetInteger( obj
, "time" ) + cur
.i_int
;
882 var_SetInteger( obj
, "time", i_time
);
886 static int ProgramCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
887 vlc_value_t oldval
, vlc_value_t newval
,
890 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
891 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
893 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_PROGRAM
, &newval
);
898 static int TitleCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
899 vlc_value_t oldval
, vlc_value_t newval
,
902 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
905 VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
907 if( !strcmp( psz_cmd
, "next-title" ) )
909 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_TITLE_NEXT
, NULL
);
911 val
.i_int
= var_GetInteger( p_input
, "title" ) + 1;
912 var_Change( p_input
, "title", VLC_VAR_CHOICESCOUNT
, &count
);
913 if( (size_t)val
.i_int
< count
)
914 var_Change( p_input
, "title", VLC_VAR_SETVALUE
, val
);
916 else if( !strcmp( psz_cmd
, "prev-title" ) )
918 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_TITLE_PREV
, NULL
);
920 val
.i_int
= var_GetInteger( p_input
, "title" ) - 1;
922 var_Change( p_input
, "title", VLC_VAR_SETVALUE
, val
);
924 else if( !strcmp( psz_cmd
, "menu-title" ) )
926 input_ControlPushHelper( p_input
, INPUT_CONTROL_NAV_MENU
, NULL
);
928 else if( !strcmp( psz_cmd
, "menu-popup" ) )
930 input_ControlPushHelper( p_input
, INPUT_CONTROL_NAV_POPUP
, NULL
);
934 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_TITLE
, &newval
);
940 static int SeekpointCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
941 vlc_value_t oldval
, vlc_value_t newval
,
944 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
947 VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
949 if( !strcmp( psz_cmd
, "next-chapter" ) )
951 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_SEEKPOINT_NEXT
, NULL
);
953 val
.i_int
= var_GetInteger( p_input
, "chapter" ) + 1;
954 var_Change( p_input
, "chapter", VLC_VAR_CHOICESCOUNT
, &count
);
955 if( (size_t)val
.i_int
< count
)
956 var_Change( p_input
, "chapter", VLC_VAR_SETVALUE
, val
);
958 else if( !strcmp( psz_cmd
, "prev-chapter" ) )
960 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_SEEKPOINT_PREV
, NULL
);
962 val
.i_int
= var_GetInteger( p_input
, "chapter" ) - 1;
964 var_Change( p_input
, "chapter", VLC_VAR_SETVALUE
, val
);
968 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_SEEKPOINT
, &newval
);
974 static int NavigationCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
975 vlc_value_t oldval
, vlc_value_t newval
,
978 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
980 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
);
982 /* Issue a title change */
983 val
.i_int
= (intptr_t)p_data
;
984 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_TITLE
, &val
);
986 var_Change( p_input
, "title", VLC_VAR_SETVALUE
, val
);
988 /* And a chapter change */
989 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_SEEKPOINT
, &newval
);
991 var_Change( p_input
, "chapter", VLC_VAR_SETVALUE
, newval
);
996 static int EsVideoCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
997 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
999 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1000 VLC_UNUSED( psz_cmd
); VLC_UNUSED( oldval
); VLC_UNUSED( p_data
);
1002 if( newval
.i_int
< 0 )
1003 newval
.i_int
= -VIDEO_ES
; /* disable video es */
1005 var_SetBool( p_input
, "video", true );
1007 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_ES
, &newval
);
1012 static int EsAudioCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
1013 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
1015 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1016 VLC_UNUSED( psz_cmd
); VLC_UNUSED( oldval
); VLC_UNUSED( p_data
);
1018 if( newval
.i_int
< 0 )
1019 newval
.i_int
= -AUDIO_ES
; /* disable audio es */
1021 var_SetBool( p_input
, "audio", true );
1023 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_ES
, &newval
);
1028 static int EsSpuCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
1029 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
1031 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1032 VLC_UNUSED( psz_cmd
); VLC_UNUSED( oldval
); VLC_UNUSED( p_data
);
1034 if( newval
.i_int
< 0 )
1035 newval
.i_int
= -SPU_ES
; /* disable spu es */
1037 var_SetBool( p_input
, "spu", true );
1039 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_ES
, &newval
);
1044 static int EsDelayCallback ( vlc_object_t
*p_this
, char const *psz_cmd
,
1045 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
1047 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1048 VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
1050 if( !strcmp( psz_cmd
, "audio-delay" ) )
1052 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_AUDIO_DELAY
, &newval
);
1054 else if( !strcmp( psz_cmd
, "spu-delay" ) )
1056 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_SPU_DELAY
, &newval
);
1061 static int BookmarkCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
1062 vlc_value_t oldval
, vlc_value_t newval
,
1065 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1066 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
1068 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_BOOKMARK
, &newval
);
1073 static int RecordCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
1074 vlc_value_t oldval
, vlc_value_t newval
,
1077 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1078 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
1080 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_RECORD_STATE
, &newval
);
1085 static int FrameNextCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
1086 vlc_value_t oldval
, vlc_value_t newval
,
1089 input_thread_t
*p_input
= (input_thread_t
*)p_this
;
1090 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_data
);
1093 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_FRAME_NEXT
, NULL
);