]> git.sesse.net Git - vlc/blob - src/input/input_ext-intf.c
765ceefa4b225f607877f4a2be974d11a3bf5b21
[vlc] / src / input / input_ext-intf.c
1 /*****************************************************************************
2  * input_ext-intf.c: services to the interface
3  *****************************************************************************
4  * Copyright (C) 1998, 1999, 2000 VideoLAN
5  * $Id: input_ext-intf.c,v 1.20 2001/04/08 07:24:47 stef Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "defs.h"
28
29 #include <string.h>                                    /* memcpy(), memset() */
30
31 #include "config.h"
32 #include "common.h"
33 #include "threads.h"
34 #include "mtime.h"
35
36 #include "intf_msg.h"
37
38 #include "stream_control.h"
39 #include "input_ext-dec.h"
40 #include "input_ext-intf.h"
41
42 #include "input.h"
43
44 /*****************************************************************************
45  * input_SetStatus: change the reading status
46  *****************************************************************************/
47 void input_SetStatus( input_thread_t * p_input, int i_mode )
48 {
49     vlc_mutex_lock( &p_input->stream.stream_lock );
50
51     switch( i_mode )
52     {
53     case INPUT_STATUS_END:
54         p_input->stream.i_new_status = PLAYING_S;
55         p_input->b_eof = 1;
56         intf_Msg( "input: end of stream" );
57         break;
58
59     case INPUT_STATUS_PLAY:
60         p_input->stream.i_new_status = PLAYING_S;
61         intf_Msg( "input: playing at normal rate" );
62         break;
63
64     case INPUT_STATUS_PAUSE:
65         /* XXX: we don't need to check i_status, because input_clock.c
66          * does it for us */
67         p_input->stream.i_new_status = PAUSE_S;
68         intf_Msg( "input: toggling pause" );
69         break;
70
71     case INPUT_STATUS_FASTER:
72         /* If we are already going too fast, go back to default rate */
73         if( p_input->stream.control.i_rate * 8 <= DEFAULT_RATE )
74         {
75             p_input->stream.i_new_status = PLAYING_S;
76             intf_Msg( "input: playing at normal rate" );
77         }
78         else
79         {
80             p_input->stream.i_new_status = FORWARD_S;
81
82             if( p_input->stream.control.i_rate < DEFAULT_RATE
83                     && p_input->stream.control.i_status == FORWARD_S )
84             {
85                 p_input->stream.i_new_rate =
86                                     p_input->stream.control.i_rate / 2;
87             }
88             else
89             {
90                 p_input->stream.i_new_rate = DEFAULT_RATE / 2;
91             }
92             intf_Msg( "input: playing at %i:1 fast forward",
93                       DEFAULT_RATE / p_input->stream.i_new_rate );
94         }
95         break;
96
97     case INPUT_STATUS_SLOWER:
98         /* If we are already going too slow, go back to default rate */
99         if( p_input->stream.control.i_rate >= 8 * DEFAULT_RATE )
100         {
101             p_input->stream.i_new_status = PLAYING_S;
102             intf_Msg( "input: playing at normal rate" );
103         }
104         else
105         {
106             p_input->stream.i_new_status = FORWARD_S;
107
108             if( p_input->stream.control.i_rate > DEFAULT_RATE
109                     && p_input->stream.control.i_status == FORWARD_S )
110             {
111                 p_input->stream.i_new_rate =
112                                     p_input->stream.control.i_rate * 2;
113             }
114             else
115             {
116                 p_input->stream.i_new_rate = DEFAULT_RATE * 2;
117             }
118             intf_Msg( "input: playing at 1:%i slow motion",
119                       p_input->stream.i_new_rate / DEFAULT_RATE );
120         }
121         break;
122
123     default:
124         break;
125     }
126
127     vlc_cond_signal( &p_input->stream.stream_wait );
128     vlc_mutex_unlock( &p_input->stream.stream_lock );
129 }
130
131 /*****************************************************************************
132  * input_SetRate: change the reading rate
133  *****************************************************************************/
134 void input_SetRate( input_thread_t * p_input, int i_mode )
135 {
136     ; /* FIXME: stub */
137 }
138  
139 /*****************************************************************************
140  * input_Seek: changes the stream postion
141  *****************************************************************************/
142 void input_Seek( input_thread_t * p_input, off_t i_position )
143 {
144     char        psz_time1[OFFSETTOTIME_MAX_SIZE];
145     char        psz_time2[OFFSETTOTIME_MAX_SIZE];
146
147     vlc_mutex_lock( &p_input->stream.stream_lock );
148     p_input->stream.p_selected_area->i_seek = i_position;
149
150     intf_Msg( "input: seeking position %lld/%lld (%s/%s)", i_position,
151                     p_input->stream.p_selected_area->i_size,
152                     input_OffsetToTime( p_input, psz_time1, i_position ),
153                     input_OffsetToTime( p_input, psz_time2,
154                                 p_input->stream.p_selected_area->i_size ) );
155
156     vlc_cond_signal( &p_input->stream.stream_wait );
157     vlc_mutex_unlock( &p_input->stream.stream_lock );
158 }
159
160 /*****************************************************************************
161  * input_OffsetToTime : converts an off_t value to a time indicator, using
162  *                      mux_rate
163  *****************************************************************************
164  * BEWARE : this function assumes that you already own the lock on
165  * p_input->stream.stream_lock
166  *****************************************************************************/
167 char * input_OffsetToTime( input_thread_t * p_input, char * psz_buffer,
168                            off_t i_offset )
169 {
170     mtime_t         i_seconds;
171
172     if( p_input->stream.i_mux_rate )
173     {
174         i_seconds = i_offset / 50 / p_input->stream.i_mux_rate;
175         snprintf( psz_buffer, OFFSETTOTIME_MAX_SIZE, "%d:%02d:%02d",
176                  (int) (i_seconds / (60 * 60)),
177                  (int) (i_seconds / 60 % 60),
178                  (int) (i_seconds % 60) );
179         return( psz_buffer );
180     }
181     else
182     {
183         /* Divide by zero is not my friend. */
184         sprintf( psz_buffer, "-:--:--" );
185         return( psz_buffer );
186     }
187 }
188
189 /*****************************************************************************
190  * input_DumpStream: dumps the contents of a stream descriptor
191  *****************************************************************************
192  * BEWARE : this function assumes that you already own the lock on
193  * p_input->stream.stream_lock
194  *****************************************************************************/
195 void input_DumpStream( input_thread_t * p_input )
196 {
197     int         i, j;
198     char        psz_time1[OFFSETTOTIME_MAX_SIZE];
199     char        psz_time2[OFFSETTOTIME_MAX_SIZE];
200
201 #define S   p_input->stream
202     intf_Msg( "input info: Dumping stream ID 0x%x", S.i_stream_id );
203     if( S.b_seekable )
204         intf_Msg( "input info: seekable stream, position: %lld/%lld (%s/%s)",
205                   S.p_selected_area->i_tell, S.p_selected_area->i_size,
206                   input_OffsetToTime( p_input, psz_time1,
207                                       S.p_selected_area->i_tell ),
208                   input_OffsetToTime( p_input, psz_time2,
209                                       S.p_selected_area->i_size ) );
210     else
211         intf_Msg( "input info: %s", S.b_pace_control ? "pace controlled" :
212                   "pace un-controlled" );
213 #undef S
214     for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
215     {
216 #define P   p_input->stream.pp_programs[i]
217         intf_Msg( "input info: Dumping program 0x%x, version %d (%s)",
218                   P->i_number, P->i_version,
219                   P->b_is_ok ? "complete" : "partial" );
220 #undef P
221         for( j = 0; j < p_input->stream.pp_programs[i]->i_es_number; j++ )
222         {
223 #define ES  p_input->stream.pp_programs[i]->pp_es[j]
224             intf_Msg( "input info: ES 0x%x, stream 0x%x, type 0x%x, %s",
225                       ES->i_id, ES->i_stream_id, ES->i_type,
226                       ES->p_decoder_fifo != NULL ? "selected" : "not selected");
227 #undef ES
228         }
229     }
230 }
231
232 /*****************************************************************************
233  * input_ChangeES: answers to a user request with calls to (Un)SelectES
234  * ---
235  * Useful since the interface plugins know p_es
236  *****************************************************************************/
237 int input_ChangeES( input_thread_t * p_input, es_descriptor_t * p_es,
238                     u8 i_cat )
239 {
240     int                     i_index;
241     int                     i;
242
243     i_index = -1;
244
245     vlc_mutex_lock( &p_input->stream.stream_lock );
246
247     for( i = 0 ; i < p_input->stream.i_selected_es_number ; i++ )
248     {
249         if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
250         {
251             i_index = i;
252             break;
253         }
254     }
255
256
257     if( p_es != NULL )
258     {
259
260     
261         if( i_index != -1 )
262         {
263             
264             if( p_input->stream.pp_selected_es[i_index] != p_es )
265             {
266                 input_UnselectES( p_input,
267                                   p_input->stream.pp_selected_es[i_index] );
268                 input_SelectES( p_input, p_es );
269                 intf_WarnMsg( 1, "input info: es selected -> %s (0x%x)",
270                                                 p_es->psz_desc, p_es->i_id );
271             }
272         }
273         else
274         {
275             input_SelectES( p_input, p_es );
276             intf_WarnMsg( 1, "input info: es selected -> %s (0x%x)",
277                           p_es->psz_desc, p_es->i_id );
278         }
279     }
280     else
281     {
282         if( i_index != -1 )
283         {
284             intf_WarnMsg( 1, "input info: es unselected -> %s (0x%x)",
285                           p_input->stream.pp_selected_es[i_index]->psz_desc,
286                           p_input->stream.pp_selected_es[i_index]->i_id );
287
288             input_UnselectES( p_input,
289                               p_input->stream.pp_selected_es[i_index] );
290         }
291     }
292
293     vlc_mutex_unlock( &p_input->stream.stream_lock );
294
295     return 0;
296 }
297
298 /*****************************************************************************
299  * input_ToggleES: answers to a user request with calls to (Un)SelectES
300  *****************************************************************************
301  * Useful since the interface plugins know p_es.
302  * It only works for audio & spu ( to be sure nothing nasty is being done ).
303  * b_select is a boolean to know if we have to select or unselect ES
304  *****************************************************************************/
305 int input_ToggleES( input_thread_t * p_input, es_descriptor_t * p_es,
306                     boolean_t b_select )
307 {
308
309     vlc_mutex_lock( &p_input->stream.stream_lock );
310
311     if( p_es != NULL )
312     {
313         if( b_select )
314         {
315             input_SelectES( p_input, p_es );
316         }
317         else
318         {
319             input_UnselectES( p_input, p_es );
320         }
321     }
322
323     vlc_mutex_unlock( &p_input->stream.stream_lock );
324
325     return 0;
326 }