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