You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1133 lines
43 KiB

/*****************************************************************************
* var.c: object variables for input thread
*****************************************************************************
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
15 years ago
* Copyright (C) 2004-2007 VLC authors and VideoLAN
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
15 years ago
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
15 years ago
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
15 years ago
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_memstream.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "input_internal.h"
/*****************************************************************************
* Callbacks
*****************************************************************************/
static int StateCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int RateCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int PositionCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int TimeCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int TimeOffsetCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int ProgramCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int TitleCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int SeekpointCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int EsVideoCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int EsAudioCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int EsSpuCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void * );
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 );
static int FrameNextCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
static int SubFpsCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
static void input_LegacyVarTitle( input_thread_t *p_input, int i_title );
static void input_LegacyVarNavigation( input_thread_t *p_input );
typedef struct
{
const char *psz_name;
vlc_callback_t callback;
} vlc_input_callback_t;
static void InputAddCallbacks( input_thread_t *, const vlc_input_callback_t * );
#ifdef CALLBACK /* For windows */
# undef CALLBACK /* We don't care of this one here */
#endif
/* List all callbacks added by input */
#define CALLBACK(name,cb) { name, cb }
static const vlc_input_callback_t p_input_callbacks[] =
{
CALLBACK( "state", StateCallback ),
CALLBACK( "rate", RateCallback ),
CALLBACK( "position", PositionCallback ),
CALLBACK( "time", TimeCallback ),
CALLBACK( "time-offset", TimeOffsetCallback ),
CALLBACK( "bookmark", BookmarkCallback ),
CALLBACK( "program", ProgramCallback ),
CALLBACK( "title", TitleCallback ),
CALLBACK( "chapter", SeekpointCallback ),
CALLBACK( "audio-delay", EsDelayCallback ),
CALLBACK( "spu-delay", EsDelayCallback ),
CALLBACK( "video-es", EsVideoCallback ),
CALLBACK( "audio-es", EsAudioCallback ),
CALLBACK( "spu-es", EsSpuCallback ),
CALLBACK( "record", RecordCallback ),
CALLBACK( "frame-next", FrameNextCallback ),
CALLBACK( "sub-fps", SubFpsCallback ),
CALLBACK( NULL, NULL )
};
#undef CALLBACK
static void Trigger( input_thread_t *p_input, int i_type )
{
var_SetInteger( p_input, "intf-event", i_type );
}
static void VarListAdd( input_thread_t *p_input,
const char *psz_variable,
int i_value, const char *psz_text )
{
vlc_value_t val;
val.i_int = i_value;
var_Change( p_input, psz_variable, VLC_VAR_ADDCHOICE, val, psz_text );
}
static void VarListDel( input_thread_t *p_input,
const char *psz_variable,
int i_value )
{
vlc_value_t val;
if( i_value >= 0 )
{
val.i_int = i_value;
var_Change( p_input, psz_variable, VLC_VAR_DELCHOICE, val );
}
else
{
var_Change( p_input, psz_variable, VLC_VAR_CLEARCHOICES );
}
}
static void VarListSelect( input_thread_t *p_input,
const char *psz_variable,
int i_value )
{
vlc_value_t val;
val.i_int = i_value;
var_Change( p_input, psz_variable, VLC_VAR_SETVALUE, val );
}
static const char *GetEsVarName( enum es_format_category_e i_cat )
{
switch( i_cat )
{
case VIDEO_ES:
return "video-es";
case AUDIO_ES:
return "audio-es";
case SPU_ES:
return "spu-es";
default:
return NULL;
}
}
static void UpdateBookmarksOption( input_thread_t *p_input )
{
input_thread_private_t *priv = input_priv(p_input);
input_item_t* item = priv->p_item;
struct vlc_memstream vstr;
vlc_memstream_open( &vstr );
vlc_memstream_puts( &vstr, "bookmarks=" );
vlc_mutex_lock( &item->lock );
var_Change( p_input, "bookmark", VLC_VAR_CLEARCHOICES );
for( int i = 0; i < priv->i_bookmark; i++ )
{
seekpoint_t const* sp = priv->pp_bookmark[i];
/* Add bookmark to choice-list */
var_Change( p_input, "bookmark", VLC_VAR_ADDCHOICE,
(vlc_value_t){ .i_int = i }, sp->psz_name );
/* Append bookmark to option-buffer */
/* TODO: escape inappropriate values */
vlc_memstream_printf( &vstr, "%s{name=%s,time=%.3f}",
i > 0 ? "," : "", sp->psz_name, secf_from_vlc_tick(sp->i_time_offset) );
}
if( vlc_memstream_close( &vstr ) )
{
vlc_mutex_unlock( &item->lock );
return;
}
/* XXX: The below is ugly and should be fixed elsewhere, but in order to
* not have more than one "bookmarks=" option associated with the item, we
* need to remove any existing ones before adding the new one. This logic
* should exist in input_item_AddOption with "OPTION_UNIQUE & <an overwrite
* flag>, but until then we handle it here. */
char** const orig_beg = &item->ppsz_options[0];
char** const orig_end = orig_beg + item->i_options;
char** end = orig_end;
for( char** option = orig_beg; option != end; )
{
if( strncmp( *option, "bookmarks=", 10 ) )
++option;
else
{
free( *option );
/* It might be tempting to optimize the below by overwriting
* *option with the value of the last element, however; we want to
* preserve the order of the other options (as behavior might
* depend on it) */
memmove( option, option + 1, ( --end - option ) * sizeof *end );
}
}
if( end != orig_end ) /* we removed at least 1 option */
{
*end = vstr.ptr;
item->i_options = end - orig_beg + 1;
vlc_mutex_unlock( &item->lock );
}
else /* nothing removed, add the usual way */
{
vlc_mutex_unlock( &item->lock );
input_item_AddOption( item, vstr.ptr, VLC_INPUT_OPTION_UNIQUE );
free( vstr.ptr );
}
}
static inline bool EsFmtIsTeletext( const es_format_t *p_fmt )
{
return p_fmt->i_cat == SPU_ES && p_fmt->i_codec == VLC_CODEC_TELETEXT;
}
void input_LegacyEvents( input_thread_t *p_input,
const struct vlc_input_event *event, void *user_data )
{
(void) user_data;
vlc_value_t val;
switch( event->type )
{
case INPUT_EVENT_STATE:
val.i_int = event->state;
var_Change( p_input, "state", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_DEAD:
break;
case INPUT_EVENT_RATE:
val.f_float = event->rate;
var_Change( p_input, "rate", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_CAPABILITIES:
var_SetBool( p_input, "can-seek",
event->capabilities & VLC_INPUT_CAPABILITIES_SEEKABLE );
var_SetBool( p_input, "can-pause",
event->capabilities & VLC_INPUT_CAPABILITIES_PAUSEABLE );
var_SetBool( p_input, "can-rate",
event->capabilities & VLC_INPUT_CAPABILITIES_CHANGE_RATE );
var_SetBool( p_input, "can-rewind",
event->capabilities & VLC_INPUT_CAPABILITIES_REWINDABLE );
var_SetBool( p_input, "can-record",
event->capabilities & VLC_INPUT_CAPABILITIES_RECORDABLE );
break;
case INPUT_EVENT_POSITION:
val.f_float = event->position.percentage;
var_Change( p_input, "position", VLC_VAR_SETVALUE, val );
val.i_int = event->position.ms;
var_Change( p_input, "time", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_LENGTH:
/* FIXME ugly + what about meta change event ? */
if( var_GetInteger( p_input, "length" ) == event->length )
return;
val.i_int = event->length;
var_Change( p_input, "length", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_TITLE:
val.i_int = event->title.action == VLC_INPUT_TITLE_NEW_LIST ? 0 : event->title.selected_idx;
var_Change( p_input, "title", VLC_VAR_SETVALUE, val );
input_LegacyVarNavigation( p_input );
input_LegacyVarTitle( p_input, val.i_int );
break;
case INPUT_EVENT_CHAPTER:
/* "chapter" */
val.i_int = event->chapter.seekpoint;
var_Change( p_input, "chapter", VLC_VAR_SETVALUE, val );
/* "title %2u" */
char psz_title[sizeof ("title ") + 3 * sizeof (int)];
sprintf( psz_title, "title %2u", event->chapter.title );
var_Change( p_input, psz_title, VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_PROGRAM:
switch (event->program.action)
{
case VLC_INPUT_PROGRAM_ADDED:
VarListAdd( p_input, "program", event->program.id,
event->program.title );
break;
case VLC_INPUT_PROGRAM_DELETED:
VarListDel( p_input, "program", event->program.id );
break;
case VLC_INPUT_PROGRAM_UPDATED:
VarListDel( p_input, "program", event->program.id );
VarListAdd( p_input, "program", event->program.id,
event->program.title );
break;
case VLC_INPUT_PROGRAM_SELECTED:
VarListSelect( p_input, "program", event->program.id );
break;
case VLC_INPUT_PROGRAM_SCRAMBLED:
if( var_GetInteger( p_input, "program" ) != event->program.id )
return;
var_SetBool( p_input, "program-scrambled", event->program.scrambled );
break;
}
break;
case INPUT_EVENT_ES:
switch (event->es.action)
{
case VLC_INPUT_ES_ADDED:
{
const char *varname = GetEsVarName( event->es.fmt->i_cat );
if( varname )
{
size_t count;
var_Change( p_input, varname, VLC_VAR_CHOICESCOUNT, &count );
if( count == 0 )
{
/* First one, we need to add the "Disable" choice */
VarListAdd( p_input, varname, -1, _("Disable") );
}
VarListAdd( p_input, varname, event->es.fmt->i_id, event->es.title );
}
if( EsFmtIsTeletext( event->es.fmt ) )
{
char psz_page[3+1];
snprintf( psz_page, sizeof(psz_page), "%d%2.2x",
event->es.fmt->subs.teletext.i_magazine,
event->es.fmt->subs.teletext.i_page );
VarListAdd( p_input, "teletext-es", event->es.fmt->i_id,
event->es.fmt->subs.teletext.i_magazine >= 0 ? psz_page : "" );
}
break;
}
case VLC_INPUT_ES_DELETED:
{
const char *varname = GetEsVarName( event->es.fmt->i_cat );
if( varname )
VarListDel( p_input, varname, event->es.fmt->i_id );
if( EsFmtIsTeletext( event->es.fmt ) )
VarListDel( p_input, "teletext-es", event->es.fmt->i_id );
break;
}
case VLC_INPUT_ES_SELECTED:
case VLC_INPUT_ES_UNSELECTED:
{
int i_id = event->es.action == VLC_INPUT_ES_SELECTED
? event->es.fmt->i_id : -1;
const char *varname = GetEsVarName( event->es.fmt->i_cat );
if( varname )
VarListSelect( p_input, varname, i_id );
if( EsFmtIsTeletext( event->es.fmt ) )
VarListSelect( p_input, "teletext-es", i_id );
break;
}
case VLC_INPUT_ES_UPDATED:
break;
}
break;
case INPUT_EVENT_RECORD:
val.b_bool = event->record;
var_Change( p_input, "record", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_ITEM_META:
break;
case INPUT_EVENT_ITEM_INFO:
break;
case INPUT_EVENT_ITEM_EPG:
break;
case INPUT_EVENT_STATISTICS:
break;
case INPUT_EVENT_SIGNAL:
val.f_float = event->signal.quality;
var_Change( p_input, "signal-quality", VLC_VAR_SETVALUE, val );
val.f_float = event->signal.strength;
var_Change( p_input, "signal-strength", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_AUDIO_DELAY:
val.i_int = event->audio_delay;
var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_SUBTITLE_DELAY:
val.i_int = event->subtitle_delay;
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_BOOKMARK:
UpdateBookmarksOption( p_input );
break;
case INPUT_EVENT_CACHE:
val.f_float = event->cache;
var_Change( p_input, "cache", VLC_VAR_SETVALUE, val );
break;
case INPUT_EVENT_VOUT:
case INPUT_EVENT_SUBITEMS:
case INPUT_EVENT_THUMBNAIL_READY:
case INPUT_EVENT_VBI_PAGE:
case INPUT_EVENT_VBI_TRANSPARENCY:
case INPUT_EVENT_SUBS_FPS:
break;
}
Trigger( p_input, event->type );
}
/*****************************************************************************
* input_LegacyVarInit:
* Create all control object variables with their callbacks
*****************************************************************************/
void input_LegacyVarInit ( input_thread_t *p_input )
{
vlc_value_t val;
var_Create( p_input, "can-seek", VLC_VAR_BOOL );
var_SetBool( p_input, "can-seek", true ); /* Fixed later*/
var_Create( p_input, "can-pause", VLC_VAR_BOOL );
var_SetBool( p_input, "can-pause", true ); /* Fixed later*/
var_Create( p_input, "can-rate", VLC_VAR_BOOL );
var_SetBool( p_input, "can-rate", false );
var_Create( p_input, "can-rewind", VLC_VAR_BOOL );
var_SetBool( p_input, "can-rewind", false );
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 );
var_Create( p_input, "cache", VLC_VAR_FLOAT );
var_SetFloat( p_input, "cache", 0.0 );
var_Create( p_input, "signal-quality", VLC_VAR_FLOAT );
var_SetFloat( p_input, "signal-quality", -1 );
var_Create( p_input, "signal-strength", VLC_VAR_FLOAT );
var_SetFloat( p_input, "signal-strength", -1 );
var_Create( p_input, "program-scrambled", VLC_VAR_BOOL );
var_SetBool( p_input, "program-scrambled", false );
/* State */
var_Create( p_input, "state", VLC_VAR_INTEGER );
val.i_int = input_priv(p_input)->i_state;
var_Change( p_input, "state", VLC_VAR_SETVALUE, val );
var_Create( p_input, "frame-next", VLC_VAR_VOID );
/* Position */
var_Create( p_input, "position", VLC_VAR_FLOAT );
/* Time */
var_Create( p_input, "time", VLC_VAR_INTEGER );
var_Create( p_input, "time-offset", VLC_VAR_INTEGER ); /* relative */
/* Bookmark */
var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, _("Bookmark") );
/* Program */
var_Get( p_input, "program", &val );
if( val.i_int <= 0 )
var_Change( p_input, "program", VLC_VAR_DELCHOICE, val );
var_Change( p_input, "program", VLC_VAR_SETTEXT, _("Program") );
/* Programs */
var_Change( p_input, "programs", VLC_VAR_SETTEXT, _("Programs") );
/* Title */
var_Create( p_input, "title", VLC_VAR_INTEGER );
var_Change( p_input, "title", VLC_VAR_SETTEXT, _("Title") );
/* Chapter */
var_Create( p_input, "chapter", VLC_VAR_INTEGER );
var_Change( p_input, "chapter", VLC_VAR_SETTEXT, _("Chapter") );
/* Delay */
var_Create( p_input, "audio-delay", VLC_VAR_INTEGER );
var_SetInteger( p_input, "audio-delay",
VLC_TICK_FROM_MS( var_GetInteger( p_input, "audio-desync" ) ) );
var_Create( p_input, "spu-delay", VLC_VAR_INTEGER );
val.i_int = -1;
/* Video ES */
var_Create( p_input, "video-es", VLC_VAR_INTEGER );
var_Change( p_input, "video-es", VLC_VAR_SETVALUE, val );
var_Change( p_input, "video-es", VLC_VAR_SETTEXT, _("Video Track") );
/* Audio ES */
var_Create( p_input, "audio-es", VLC_VAR_INTEGER );
var_Change( p_input, "audio-es", VLC_VAR_SETVALUE, val );
var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, _("Audio Track") );
/* Spu ES */
var_Create( p_input, "spu-es", VLC_VAR_INTEGER );
var_Change( p_input, "spu-es", VLC_VAR_SETVALUE, val );
var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, _("Subtitle Track") );
var_Create( p_input, "spu-choice", VLC_VAR_INTEGER );
var_SetInteger( p_input, "spu-choice", -1 );
var_Create( p_input, "length", VLC_VAR_INTEGER );
var_Create( p_input, "bit-rate", VLC_VAR_INTEGER );
var_Create( p_input, "sample-rate", VLC_VAR_INTEGER );
/* Special "intf-event" variable. */
var_Create( p_input, "intf-event", VLC_VAR_INTEGER );
var_Create( p_input, "sub-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
/* Add all callbacks
* XXX we put callback only in non preparsing mode. We need to create the variable
* unless someone want to check all var_Get/var_Change return value ... */
if( !input_priv(p_input)->b_preparsing )
InputAddCallbacks( p_input, p_input_callbacks );
}
/*****************************************************************************
* input_LegacyVarNavigation:
* Create all remaining control object variables
*****************************************************************************/
static void input_LegacyVarNavigation( input_thread_t *p_input )
{
/* Create more command variables */
if( input_priv(p_input)->i_title > 1 )
{
if( var_Type( p_input, "next-title" ) == 0 ) {
var_Create( p_input, "next-title", VLC_VAR_VOID );
var_Change( p_input, "next-title", VLC_VAR_SETTEXT,
_("Next title") );
var_AddCallback( p_input, "next-title", TitleCallback, NULL );
}
if( var_Type( p_input, "prev-title" ) == 0 ) {
var_Create( p_input, "prev-title", VLC_VAR_VOID );
var_Change( p_input, "prev-title", VLC_VAR_SETTEXT,
_("Previous title") );
var_AddCallback( p_input, "prev-title", TitleCallback, NULL );
}
if( var_Type( p_input, "menu-title" ) == 0 ) {
var_Create( p_input, "menu-title", VLC_VAR_VOID );
var_Change( p_input, "menu-title", VLC_VAR_SETTEXT,
_("Menu title") );
var_AddCallback( p_input, "menu-title", TitleCallback, NULL );
}
if( var_Type( p_input, "menu-popup" ) == 0 ) {
var_Create( p_input, "menu-popup", VLC_VAR_VOID );
var_Change( p_input, "menu-popup", VLC_VAR_SETTEXT,
_("Menu popup") );
var_AddCallback( p_input, "menu-popup", TitleCallback, NULL );
}
}
/* Create titles and chapters */
var_Change( p_input, "title", VLC_VAR_CLEARCHOICES );
for( int i = 0; i < input_priv(p_input)->i_title; i++ )
{
vlc_value_t val2, text2;
char title[sizeof("title ") + 3 * sizeof (int)];
/* Add Navigation entries */
sprintf( title, "title %2u", i );
var_Destroy( p_input, title );
var_Create( p_input, title, VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
var_AddCallback( p_input, title, NavigationCallback, NULL );
char psz_length[MSTRTIME_MAX_SIZE + sizeof(" []")];
if( input_priv(p_input)->title[i]->i_length > 0 )
{
strcpy( psz_length, " [" );
secstotimestr( &psz_length[2], SEC_FROM_VLC_TICK(input_priv(p_input)->title[i]->i_length) );
strcat( psz_length, "]" );
}
else
psz_length[0] = '\0';
char *titlestr;
if( input_priv(p_input)->title[i]->psz_name == NULL ||
*input_priv(p_input)->title[i]->psz_name == '\0' )
{
if( asprintf( &titlestr, _("Title %i%s"),
i + input_priv(p_input)->i_title_offset, psz_length ) == -1 )
continue;
}
else
{
if( asprintf( &titlestr, "%s%s",
input_priv(p_input)->title[i]->psz_name, psz_length ) == -1 )
continue;
}
/* Add title choice */
val2.i_int = i;
var_Change( p_input, "title", VLC_VAR_ADDCHOICE, val2,
(const char *)titlestr );
free( titlestr );
for( int j = 0; j < input_priv(p_input)->title[i]->i_seekpoint; j++ )
{
val2.i_int = j;
if( input_priv(p_input)->title[i]->seekpoint[j]->psz_name == NULL ||
*input_priv(p_input)->title[i]->seekpoint[j]->psz_name == '\0' )
{
/* Default value */
if( asprintf( &text2.psz_string, _("Chapter %i"),
j + input_priv(p_input)->i_seekpoint_offset ) == -1 )
continue;
}
else
{
text2.psz_string =
strdup( input_priv(p_input)->title[i]->seekpoint[j]->psz_name );
}
var_Change( p_input, title, VLC_VAR_ADDCHOICE, val2,
(const char *)text2.psz_string );
free( text2.psz_string );
}
}
}
/*****************************************************************************
* input_LegacyVarTitle:
* Create all variables for a title
*****************************************************************************/
static void input_LegacyVarTitle( input_thread_t *p_input, int i_title )
{
const input_title_t *t = input_priv(p_input)->title[i_title];
vlc_value_t text;
int i;
/* Create/Destroy command variables */
if( t->i_seekpoint <= 1 )
{
var_Destroy( p_input, "next-chapter" );
var_Destroy( p_input, "prev-chapter" );
}
else if( var_Type( p_input, "next-chapter" ) == 0 )
{
var_Create( p_input, "next-chapter", VLC_VAR_VOID );
var_Change( p_input, "next-chapter", VLC_VAR_SETTEXT,
_("Next chapter") );
var_AddCallback( p_input, "next-chapter", SeekpointCallback, NULL );
var_Create( p_input, "prev-chapter", VLC_VAR_VOID );
var_Change( p_input, "prev-chapter", VLC_VAR_SETTEXT,
_("Previous chapter") );
var_AddCallback( p_input, "prev-chapter", SeekpointCallback, NULL );
}
/* Build chapter list */
var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES );
for( i = 0; i < t->i_seekpoint; i++ )
{
vlc_value_t val;
val.i_int = i;
if( t->seekpoint[i]->psz_name == NULL ||
*t->seekpoint[i]->psz_name == '\0' )
{
/* Default value */
if( asprintf( &text.psz_string, _("Chapter %i"),
i + input_priv(p_input)->i_seekpoint_offset ) == -1 )
continue;
}
else
{
text.psz_string = strdup( t->seekpoint[i]->psz_name );
}
var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, val,
(const char *)text.psz_string );
free( text.psz_string );
}
}
/*****************************************************************************
* input_ConfigVarInit:
* Create all config object variables
*****************************************************************************/
void input_ConfigVarInit ( input_thread_t *p_input )
{
/* Create Object Variables for private use only */
if( !input_priv(p_input)->b_preparsing )
{
var_Create( p_input, "video", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "spu", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "video-track", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "audio-track", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-track", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "audio-language",
VLC_VAR_STRING|VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-language",
VLC_VAR_STRING|VLC_VAR_DOINHERIT );
var_Create( p_input, "menu-language",
VLC_VAR_STRING|VLC_VAR_DOINHERIT );
var_Create( p_input, "video-track-id",
VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "audio-track-id",
VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-track-id",
VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-file", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-autodetect-file", VLC_VAR_BOOL |
VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-autodetect-path", VLC_VAR_STRING |
VLC_VAR_DOINHERIT );
var_Create( p_input, "sub-autodetect-fuzzy", VLC_VAR_INTEGER |
VLC_VAR_DOINHERIT );
var_Create( p_input, "sout", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-all", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-video", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-spu", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-keep", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "input-repeat",
VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "start-time", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
var_Create( p_input, "stop-time", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
var_Create( p_input, "run-time", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
var_Create( p_input, "input-fast-seek", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
var_Create( p_input, "input-slave",
VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "audio-desync",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_input, "cr-average",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_input, "clock-synchro",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "programs", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_input, "rate", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
}
/* */
var_Create( p_input, "input-record-native", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
/* */
var_Create( p_input, "access", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "demux", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "demux-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "stream-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Meta */
var_Create( p_input, "meta-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "meta-author", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "meta-artist", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "meta-genre", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "meta-copyright", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
var_Create( p_input, "meta-description", VLC_VAR_STRING|VLC_VAR_DOINHERIT);
var_Create( p_input, "meta-date", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "meta-url", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Inherited by demux/subtitle.c */
var_Create( p_input, "sub-original-fps", VLC_VAR_FLOAT );
}
/*****************************************************************************
* Callbacks managements:
*****************************************************************************/
static void InputAddCallbacks( input_thread_t *p_input,
const vlc_input_callback_t *p_callbacks )
{
int i;
for( i = 0; p_callbacks[i].psz_name != NULL; i++ )
var_AddCallback( p_input,
p_callbacks[i].psz_name,
p_callbacks[i].callback, NULL );
}
/*****************************************************************************
* All Callbacks:
*****************************************************************************/
static int StateCallback( 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);
if( newval.i_int == PLAYING_S || newval.i_int == PAUSE_S )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_STATE, &newval );
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}
static int RateCallback( 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(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_cmd);
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_RATE, &newval );
return VLC_SUCCESS;
}
static int PositionCallback( 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);
/* Update "length" for better intf behaviour */
const vlc_tick_t i_length = var_GetInteger( p_input, "length" );
if( i_length > 0 && newval.f_float >= 0.f && newval.f_float <= 1.f )
{
vlc_value_t val;
val.i_int = i_length * newval.f_float;
var_Change( p_input, "time", VLC_VAR_SETVALUE, val );
}
input_SetPosition( p_input, newval.f_float,
var_GetBool( p_input, "input-fast-seek" ) );
return VLC_SUCCESS;
}
static int TimeCallback( 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);
/* Update "position" for better intf behaviour */
const vlc_tick_t i_length = var_GetInteger( p_input, "length" );
if( i_length > 0 && newval.i_int >= 0 && newval.i_int <= i_length )
{
vlc_value_t val;
val.f_float = (double)newval.i_int/(double)i_length;
var_Change( p_input, "position", VLC_VAR_SETVALUE, val );
/*
* Notify the intf that a new event has been occurred.
* XXX this is a bit hackish but it's the only way to do it now.
*/
var_SetInteger( p_input, "intf-event", INPUT_EVENT_POSITION );
}
input_SetTime( p_input, newval.i_int,
var_GetBool( p_input, "input-fast-seek" ) );
return VLC_SUCCESS;
}
static int TimeOffsetCallback( vlc_object_t *obj, char const *varname,
vlc_value_t prev, vlc_value_t cur, void *data )
{
VLC_UNUSED(varname); VLC_UNUSED(prev); VLC_UNUSED(data);
vlc_tick_t i_time = var_GetInteger( obj, "time" ) + cur.i_int;
if( i_time < 0 )
i_time = 0;
var_SetInteger( obj, "time", i_time );
return VLC_SUCCESS;
}
static int ProgramCallback( 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_ControlPushHelper( p_input, INPUT_CONTROL_SET_PROGRAM, &newval );
return VLC_SUCCESS;
}
static int TitleCallback( 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_value_t val;
size_t count;
VLC_UNUSED(oldval); VLC_UNUSED(p_data);
if( !strcmp( psz_cmd, "next-title" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_TITLE_NEXT, NULL );
val.i_int = var_GetInteger( p_input, "title" ) + 1;
var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &count );
if( (size_t)val.i_int < count )
var_Change( p_input, "title", VLC_VAR_SETVALUE, val );
}
else if( !strcmp( psz_cmd, "prev-title" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_TITLE_PREV, NULL );
val.i_int = var_GetInteger( p_input, "title" ) - 1;
if( val.i_int >= 0 )
var_Change( p_input, "title", VLC_VAR_SETVALUE, val );
}
else if( !strcmp( psz_cmd, "menu-title" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_NAV_MENU, NULL );
}
else if( !strcmp( psz_cmd, "menu-popup" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_NAV_POPUP, NULL );
}
else
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_TITLE, &newval );
}
return VLC_SUCCESS;
}
static int SeekpointCallback( 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_value_t val;
size_t count;
VLC_UNUSED(oldval); VLC_UNUSED(p_data);
if( !strcmp( psz_cmd, "next-chapter" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_SEEKPOINT_NEXT, NULL );
val.i_int = var_GetInteger( p_input, "chapter" ) + 1;
var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &count );
if( (size_t)val.i_int < count )
var_Change( p_input, "chapter", VLC_VAR_SETVALUE, val );
}
else if( !strcmp( psz_cmd, "prev-chapter" ) )
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_SEEKPOINT_PREV, NULL );
val.i_int = var_GetInteger( p_input, "chapter" ) - 1;
if( val.i_int >= 0 )
var_Change( p_input, "chapter", VLC_VAR_SETVALUE, val );
}
else
{
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_SEEKPOINT, &newval );
}
return VLC_SUCCESS;
}
static int NavigationCallback( 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_value_t val;
VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
/* Issue a title change */
sscanf(psz_cmd, "title %"SCNu64, &val.i_int);
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_TITLE, &val );
var_Change( p_input, "title", VLC_VAR_SETVALUE, val );
/* And a chapter change */
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_SEEKPOINT, &newval );
var_Change( p_input, "chapter", VLC_VAR_SETVALUE, newval );
(void) p_data;
return VLC_SUCCESS;
}
static int EsVideoCallback( 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 );
if( newval.i_int < 0 )
newval.i_int = -VIDEO_ES; /* disable video es */
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_ES_BY_ID, &newval );
return VLC_SUCCESS;
}
static int EsAudioCallback( 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 );
if( newval.i_int < 0 )
newval.i_int = -AUDIO_ES; /* disable audio es */
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_ES_BY_ID, &newval );
return VLC_SUCCESS;
}
static int EsSpuCallback( 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 );
if( newval.i_int < 0 )
newval.i_int = -SPU_ES; /* disable spu es */
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_ES_BY_ID, &newval );
return VLC_SUCCESS;
}
static int EsDelayCallback ( 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(oldval); VLC_UNUSED(p_data);
input_control_param_t param = {
.delay = {
.b_absolute = true,
.i_val = newval.i_int,
},
};
if( !strcmp( psz_cmd, "audio-delay" ) )
input_ControlPush( p_input, INPUT_CONTROL_SET_AUDIO_DELAY, &param );
else if( !strcmp( psz_cmd, "spu-delay" ) )
input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY, &param );
return VLC_SUCCESS;
}
static int BookmarkCallback( 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_ControlPushHelper( p_input, INPUT_CONTROL_SET_BOOKMARK, &newval );
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_ControlPushHelper( p_input, INPUT_CONTROL_SET_RECORD_STATE, &newval );
return VLC_SUCCESS;
}
static int FrameNextCallback( 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);
18 years ago
VLC_UNUSED(newval);
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_FRAME_NEXT, NULL );
return VLC_SUCCESS;
}
static int SubFpsCallback( 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);
VLC_UNUSED(newval);
input_ControlPushHelper( p_input, INPUT_CONTROL_SET_SUBS_FPS, &newval );
return VLC_SUCCESS;
}