gui: macos: use float for rate
[vlc.git] / src / input / control.c
blob2aa79e67b3047bce79a3c7d3849b67f75058b7cf
1 /*****************************************************************************
2 * control.c
3 *****************************************************************************
4 * Copyright (C) 1999-2015 VLC authors and VideoLAN
6 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
27 #include <vlc_common.h>
28 #include <vlc_renderer_discovery.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <assert.h>
34 #include "input_internal.h"
35 #include "event.h"
36 #include "resource.h"
37 #include "es_out.h"
39 /****************************************************************************
40 * input_Control
41 ****************************************************************************/
42 /**
43 * Control function for inputs.
44 * \param p_input input handle
45 * \param i_query query type
46 * \return VLC_SUCCESS if ok
48 int input_Control( input_thread_t *p_input, int i_query, ... )
50 va_list args;
51 int i_result;
53 va_start( args, i_query );
54 i_result = input_vaControl( p_input, i_query, args );
55 va_end( args );
57 return i_result;
60 int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
62 input_thread_private_t *priv = input_priv(p_input);
63 seekpoint_t *p_bkmk, ***ppp_bkmk;
64 int i_bkmk = 0;
65 int *pi_bkmk;
66 bool b_bool;
68 char *psz;
69 vlc_value_t val;
71 switch( i_query )
73 case INPUT_NAV_ACTIVATE:
74 case INPUT_NAV_UP:
75 case INPUT_NAV_DOWN:
76 case INPUT_NAV_LEFT:
77 case INPUT_NAV_RIGHT:
78 case INPUT_NAV_POPUP:
79 case INPUT_NAV_MENU:
80 input_ControlPushHelper( p_input, i_query - INPUT_NAV_ACTIVATE
81 + INPUT_CONTROL_NAV_ACTIVATE, NULL );
82 return VLC_SUCCESS;
84 case INPUT_ADD_BOOKMARK:
85 p_bkmk = va_arg( args, seekpoint_t * );
86 p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
88 vlc_mutex_lock( &priv->p_item->lock );
89 if( !p_bkmk->psz_name )
91 if( asprintf( &p_bkmk->psz_name, _("Bookmark %i"),
92 priv->i_bookmark ) == -1 )
93 p_bkmk->psz_name = NULL;
96 if( p_bkmk->psz_name )
97 TAB_APPEND( priv->i_bookmark, priv->pp_bookmark, p_bkmk );
98 else
100 vlc_seekpoint_Delete( p_bkmk );
101 p_bkmk = NULL;
103 vlc_mutex_unlock( &priv->p_item->lock );
105 input_SendEventBookmark( p_input );
107 return p_bkmk ? VLC_SUCCESS : VLC_EGENERIC;
109 case INPUT_CHANGE_BOOKMARK:
110 p_bkmk = va_arg( args, seekpoint_t * );
111 i_bkmk = va_arg( args, int );
113 vlc_mutex_lock( &priv->p_item->lock );
114 if( i_bkmk < priv->i_bookmark )
116 p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
117 if( p_bkmk )
119 vlc_seekpoint_Delete( priv->pp_bookmark[i_bkmk] );
120 priv->pp_bookmark[i_bkmk] = p_bkmk;
123 else p_bkmk = NULL;
124 vlc_mutex_unlock( &priv->p_item->lock );
126 input_SendEventBookmark( p_input );
128 return p_bkmk ? VLC_SUCCESS : VLC_EGENERIC;
130 case INPUT_DEL_BOOKMARK:
131 i_bkmk = va_arg( args, int );
133 vlc_mutex_lock( &priv->p_item->lock );
134 if( i_bkmk < priv->i_bookmark )
136 p_bkmk = priv->pp_bookmark[i_bkmk];
137 TAB_REMOVE( priv->i_bookmark, priv->pp_bookmark, p_bkmk );
138 vlc_seekpoint_Delete( p_bkmk );
140 vlc_mutex_unlock( &priv->p_item->lock );
142 input_SendEventBookmark( p_input );
144 return VLC_SUCCESS;
146 vlc_mutex_unlock( &priv->p_item->lock );
148 return VLC_EGENERIC;
150 case INPUT_GET_BOOKMARKS:
151 ppp_bkmk = va_arg( args, seekpoint_t *** );
152 pi_bkmk = va_arg( args, int * );
154 vlc_mutex_lock( &priv->p_item->lock );
155 if( priv->i_bookmark )
157 int i;
159 *pi_bkmk = priv->i_bookmark;
160 *ppp_bkmk = vlc_alloc( priv->i_bookmark, sizeof(seekpoint_t *) );
161 for( i = 0; i < priv->i_bookmark; i++ )
163 (*ppp_bkmk)[i] =
164 vlc_seekpoint_Duplicate( input_priv(p_input)->pp_bookmark[i] );
167 vlc_mutex_unlock( &priv->p_item->lock );
168 return VLC_SUCCESS;
170 else
172 *ppp_bkmk = NULL;
173 *pi_bkmk = 0;
175 vlc_mutex_unlock( &priv->p_item->lock );
176 return VLC_EGENERIC;
178 break;
180 case INPUT_CLEAR_BOOKMARKS:
181 vlc_mutex_lock( &priv->p_item->lock );
182 for( int i = 0; i < priv->i_bookmark; ++i )
183 vlc_seekpoint_Delete( priv->pp_bookmark[i] );
185 TAB_CLEAN( priv->i_bookmark, priv->pp_bookmark );
186 vlc_mutex_unlock( &priv->p_item->lock );
188 input_SendEventBookmark( p_input );
189 return VLC_SUCCESS;
191 case INPUT_SET_BOOKMARK:
192 i_bkmk = va_arg( args, int );
194 val.i_int = i_bkmk;
195 input_ControlPushHelper( p_input, INPUT_CONTROL_SET_BOOKMARK, &val );
197 return VLC_SUCCESS;
199 case INPUT_GET_BOOKMARK:
200 p_bkmk = va_arg( args, seekpoint_t * );
202 vlc_mutex_lock( &priv->p_item->lock );
203 *p_bkmk = priv->bookmark;
204 vlc_mutex_unlock( &priv->p_item->lock );
205 return VLC_SUCCESS;
207 case INPUT_GET_FULL_TITLE_INFO:
209 vlc_mutex_lock( &priv->p_item->lock );
210 unsigned count = priv->i_title;
211 input_title_t **array = vlc_alloc( count, sizeof (*array) );
213 if( count > 0 && unlikely(array == NULL) )
215 vlc_mutex_unlock( &priv->p_item->lock );
216 return VLC_ENOMEM;
219 for( unsigned i = 0; i < count; i++ )
220 array[i] = vlc_input_title_Duplicate( priv->title[i] );
222 vlc_mutex_unlock( &priv->p_item->lock );
224 *va_arg( args, input_title_t *** ) = array;
225 *va_arg( args, int * ) = count;
226 return VLC_SUCCESS;
229 case INPUT_ADD_SLAVE:
231 enum slave_type type = va_arg( args, enum slave_type );
232 psz = va_arg( args, char * );
233 b_bool = va_arg( args, int );
234 bool b_notify = va_arg( args, int );
235 bool b_check_ext = va_arg( args, int );
237 if( !psz || ( type != SLAVE_TYPE_SPU && type != SLAVE_TYPE_AUDIO ) )
238 return VLC_EGENERIC;
239 if( b_check_ext && type == SLAVE_TYPE_SPU &&
240 !subtitles_Filter( psz ) )
241 return VLC_EGENERIC;
243 input_item_slave_t *p_slave =
244 input_item_slave_New( psz, type, SLAVE_PRIORITY_USER );
245 if( !p_slave )
246 return VLC_ENOMEM;
247 p_slave->b_forced = b_bool;
249 val.p_address = p_slave;
250 input_ControlPushHelper( p_input, INPUT_CONTROL_ADD_SLAVE, &val );
251 if( b_notify )
253 vout_thread_t *p_vout = input_GetVout( p_input );
254 if( p_vout )
256 switch( type )
258 case SLAVE_TYPE_AUDIO:
259 vout_OSDMessage(p_vout, VOUT_SPU_CHANNEL_OSD, "%s",
260 vlc_gettext("Audio track added"));
261 break;
262 case SLAVE_TYPE_SPU:
263 vout_OSDMessage(p_vout, VOUT_SPU_CHANNEL_OSD, "%s",
264 vlc_gettext("Subtitle track added"));
265 break;
267 vlc_object_release( (vlc_object_t *)p_vout );
270 return VLC_SUCCESS;
273 case INPUT_RESTART_ES_BY_ID:
274 val.i_int = va_arg( args, int );
275 input_ControlPushHelper( p_input, INPUT_CONTROL_RESTART_ES_BY_ID, &val );
276 return VLC_SUCCESS;
278 case INPUT_UPDATE_VIEWPOINT:
279 case INPUT_SET_INITIAL_VIEWPOINT:
281 input_control_param_t param;
282 param.viewpoint = *va_arg( args, const vlc_viewpoint_t* );
283 if ( i_query == INPUT_SET_INITIAL_VIEWPOINT )
284 input_ControlPush( p_input, INPUT_CONTROL_SET_INITIAL_VIEWPOINT,
285 &param );
286 else if ( va_arg( args, int ) )
287 input_ControlPush( p_input, INPUT_CONTROL_SET_VIEWPOINT, &param);
288 else
289 input_ControlPush( p_input, INPUT_CONTROL_UPDATE_VIEWPOINT, &param );
290 return VLC_SUCCESS;
293 case INPUT_GET_AOUT:
295 audio_output_t *p_aout = input_resource_HoldAout( priv->p_resource );
296 if( !p_aout )
297 return VLC_EGENERIC;
299 audio_output_t **pp_aout = va_arg( args, audio_output_t** );
300 *pp_aout = p_aout;
301 return VLC_SUCCESS;
304 case INPUT_GET_VOUTS:
306 vout_thread_t ***ppp_vout = va_arg( args, vout_thread_t*** );
307 size_t *pi_vout = va_arg( args, size_t * );
309 input_resource_HoldVouts( priv->p_resource, ppp_vout, pi_vout );
310 if( *pi_vout == 0 )
311 return VLC_EGENERIC;
312 return VLC_SUCCESS;
315 case INPUT_GET_ES_OBJECTS:
317 const int i_id = va_arg( args, int );
318 vlc_object_t **pp_decoder = va_arg( args, vlc_object_t ** );
319 vout_thread_t **pp_vout = va_arg( args, vout_thread_t ** );
320 audio_output_t **pp_aout = va_arg( args, audio_output_t ** );
322 return es_out_Control( priv->p_es_out_display,
323 ES_OUT_GET_ES_OBJECTS_BY_ID, i_id,
324 pp_decoder, pp_vout, pp_aout );
327 case INPUT_GET_PCR_SYSTEM:
329 vlc_tick_t *pi_system = va_arg( args, vlc_tick_t * );
330 vlc_tick_t *pi_delay = va_arg( args, vlc_tick_t * );
331 return es_out_ControlGetPcrSystem( priv->p_es_out_display, pi_system, pi_delay );
334 case INPUT_MODIFY_PCR_SYSTEM:
336 bool b_absolute = va_arg( args, int );
337 vlc_tick_t i_system = va_arg( args, vlc_tick_t );
338 return es_out_ControlModifyPcrSystem( priv->p_es_out_display, b_absolute, i_system );
341 case INPUT_SET_RENDERER:
343 vlc_renderer_item_t* p_item = va_arg( args, vlc_renderer_item_t* );
344 val.p_address = p_item ? vlc_renderer_item_hold( p_item ) : NULL;
345 input_ControlPushHelper( p_input, INPUT_CONTROL_SET_RENDERER, &val );
346 return VLC_SUCCESS;
349 default:
350 msg_Err( p_input, "unknown query 0x%x in %s", i_query, __func__ );
351 return VLC_EGENERIC;