1 /*****************************************************************************
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 *****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_renderer_discovery.h>
34 #include "input_internal.h"
39 /****************************************************************************
41 ****************************************************************************/
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
, ... )
53 va_start( args
, i_query
);
54 i_result
= input_vaControl( p_input
, i_query
, args
);
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
;
73 case INPUT_NAV_ACTIVATE
:
80 input_ControlPushHelper( p_input
, i_query
- INPUT_NAV_ACTIVATE
81 + INPUT_CONTROL_NAV_ACTIVATE
, NULL
);
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
);
100 vlc_seekpoint_Delete( p_bkmk
);
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
);
119 vlc_seekpoint_Delete( priv
->pp_bookmark
[i_bkmk
] );
120 priv
->pp_bookmark
[i_bkmk
] = p_bkmk
;
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
);
146 vlc_mutex_unlock( &priv
->p_item
->lock
);
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
)
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
++ )
164 vlc_seekpoint_Duplicate( input_priv(p_input
)->pp_bookmark
[i
] );
167 vlc_mutex_unlock( &priv
->p_item
->lock
);
175 vlc_mutex_unlock( &priv
->p_item
->lock
);
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
);
191 case INPUT_SET_BOOKMARK
:
192 i_bkmk
= va_arg( args
, int );
195 input_ControlPushHelper( p_input
, INPUT_CONTROL_SET_BOOKMARK
, &val
);
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
);
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
);
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
;
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
) )
239 if( b_check_ext
&& type
== SLAVE_TYPE_SPU
&&
240 !subtitles_Filter( psz
) )
243 input_item_slave_t
*p_slave
=
244 input_item_slave_New( psz
, type
, SLAVE_PRIORITY_USER
);
247 p_slave
->b_forced
= b_bool
;
249 val
.p_address
= p_slave
;
250 input_ControlPushHelper( p_input
, INPUT_CONTROL_ADD_SLAVE
, &val
);
253 vout_thread_t
*p_vout
= input_GetVout( p_input
);
258 case SLAVE_TYPE_AUDIO
:
259 vout_OSDMessage(p_vout
, VOUT_SPU_CHANNEL_OSD
, "%s",
260 vlc_gettext("Audio track added"));
263 vout_OSDMessage(p_vout
, VOUT_SPU_CHANNEL_OSD
, "%s",
264 vlc_gettext("Subtitle track added"));
267 vlc_object_release( (vlc_object_t
*)p_vout
);
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
);
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
,
286 else if ( va_arg( args
, int ) )
287 input_ControlPush( p_input
, INPUT_CONTROL_SET_VIEWPOINT
, ¶m
);
289 input_ControlPush( p_input
, INPUT_CONTROL_UPDATE_VIEWPOINT
, ¶m
);
295 audio_output_t
*p_aout
= input_resource_HoldAout( priv
->p_resource
);
299 audio_output_t
**pp_aout
= va_arg( args
, audio_output_t
** );
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
);
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
);
350 msg_Err( p_input
, "unknown query 0x%x in %s", i_query
, __func__
);