Make Zorglub less unhappy
[vlc.git] / src / control / util.c
1 /*****************************************************************************
2  * util.c: Utility functions and exceptions management
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id: vlc.c 10786 2005-04-23 23:19:17Z zorglub $
6  *
7  * Authors: Olivier Aubert <olivier.aubert@liris.univ-lyon1.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 #include <vlc/control.h>
25
26 #include <vlc/intf.h>
27 #include <vlc/vout.h>
28 #include <vlc/aout.h>
29 #include <vlc_demux.h>
30
31 #include <osd.h>
32
33 #define HAS_SNAPSHOT 1
34
35 #ifdef HAS_SNAPSHOT
36 #include <snapshot.h>
37 #endif
38
39 #include <stdlib.h>                                      /* malloc(), free() */
40 #include <string.h>
41
42 #include <errno.h>                                                 /* ENOMEM */
43 #include <stdio.h>
44 #include <ctype.h>
45
46 #ifdef HAVE_UNISTD_H
47 #    include <unistd.h>
48 #endif
49
50 #ifdef HAVE_SYS_TIME_H
51 #    include <sys/time.h>
52 #endif
53 #include <sys/types.h>
54
55 #define RAISE( c, m )  exception->code = c; \
56                        exception->message = strdup(m);
57
58 long long mediacontrol_unit_convert( input_thread_t *p_input,
59                                      mediacontrol_PositionKey from,
60                                      mediacontrol_PositionKey to,
61                                      long long value )
62 {
63     if( to == from )
64         return value;
65
66     /* For all conversions, we need data from p_input */
67     if( !p_input )
68         return 0;
69
70     switch( from )
71     {
72     case mediacontrol_MediaTime:
73         if( to == mediacontrol_ByteCount )
74         {
75             /* FIXME */
76             /* vlc < 0.8 API */
77             /* return value * 50 * p_input->stream.i_mux_rate / 1000; */
78             return 0;
79         }
80         if( to == mediacontrol_SampleCount )
81         {
82             double f_fps;
83
84             if( demux2_Control( p_input->input.p_demux, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
85                 return 0;
86             else
87                 return( value * f_fps / 1000.0 );
88         }
89         /* Cannot happen */
90         /* See http://catb.org/~esr/jargon/html/entry/can't-happen.html */
91         break;
92
93     case mediacontrol_SampleCount:
94     {
95         double f_fps;
96
97         if( demux2_Control( p_input->input.p_demux, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
98             return 0;
99
100         if( to == mediacontrol_ByteCount )
101         {
102             /* FIXME */
103             /* vlc < 0.8 API */
104 /*             return ( long long )( value * 50 * p_input->stream.i_mux_rate / f_fps ); */
105             return 0;
106         }
107
108         if( to == mediacontrol_MediaTime )
109             return( long long )( value * 1000.0 / ( double )f_fps );
110
111         /* Cannot happen */
112         break;
113     }
114     case mediacontrol_ByteCount:
115         /* FIXME */
116         return 0;
117 /* vlc < 0.8 API: */
118
119 //         if( p_input->stream.i_mux_rate == 0 )
120 //             return 0;
121 // 
122 //         /* Convert an offset into milliseconds. Taken from input_ext-intf.c.
123 //            The 50 hardcoded constant comes from the definition of i_mux_rate :
124 //            i_mux_rate : the rate we read the stream (in units of 50 bytes/s) ;
125 //            0 if undef */
126 //         if( to == mediacontrol_MediaTime )
127 //             return ( long long )( 1000 * value / 50 / p_input->stream.i_mux_rate );
128 // 
129 //         if( to == mediacontrol_SampleCount )
130 //         {
131 //             double f_fps;
132 //             if( demux2_Control( p_input->input.p_demux, DEMUX_GET_FPS, &f_fps ) || f_fps < 0.1 )
133 //                 return 0;
134 //             else
135 //                 return ( long long )( value * f_fps / 50 / p_input->stream.i_mux_rate );
136 //         }
137         /* Cannot happen */
138         break;
139     }
140     /* Cannot happen */
141     return 0;
142 }
143
144 /* Converts a mediacontrol_Position into a time in microseconds in
145    movie clock time */
146 long long
147 mediacontrol_position2microsecond( input_thread_t* p_input, const mediacontrol_Position * pos )
148 {
149     switch( pos->origin )
150     {
151     case mediacontrol_AbsolutePosition:
152         return ( 1000 * mediacontrol_unit_convert( p_input,
153                                                    pos->key, /* from */
154                                                    mediacontrol_MediaTime,  /* to */
155                                                    pos->value ) );
156         break;
157     case mediacontrol_RelativePosition:
158     {
159         long long l_pos;
160         vlc_value_t val;
161
162         val.i_time = 0;
163         if( p_input )
164         {
165             var_Get( p_input, "time", &val );
166         }
167
168         l_pos = 1000 * mediacontrol_unit_convert( p_input,
169                                                   pos->key,
170                                                   mediacontrol_MediaTime,
171                                                   pos->value );
172         return val.i_time + l_pos;
173         break;
174     }
175     case mediacontrol_ModuloPosition:
176     {
177         long long l_pos;
178         vlc_value_t val;
179
180         val.i_time = 0;
181         if( p_input )
182         {
183             var_Get( p_input, "length", &val );
184         }
185
186         if( val.i_time > 0)
187         {
188             l_pos = ( 1000 * mediacontrol_unit_convert( p_input,
189                                                         pos->key,
190                                                         mediacontrol_MediaTime,
191                                                         pos->value ) );
192         }
193         else
194             l_pos = 0;
195
196         return l_pos % val.i_time;
197         break;
198     }
199     }
200     return 0;
201 }
202
203 mediacontrol_RGBPicture*
204 mediacontrol_RGBPicture__alloc( int datasize )
205 {
206     mediacontrol_RGBPicture* pic;
207
208     pic = ( mediacontrol_RGBPicture * )malloc( sizeof( mediacontrol_RGBPicture ) );
209     if( ! pic )
210         return NULL;
211
212     pic->size = datasize;
213     pic->data = ( char* )malloc( datasize );
214     return pic;
215 }
216
217 void
218 mediacontrol_RGBPicture__free( mediacontrol_RGBPicture* pic )
219 {
220     if( pic )
221         free( pic->data );
222     free( pic );
223 }
224
225 mediacontrol_PlaylistSeq*
226 mediacontrol_PlaylistSeq__alloc( int size )
227 {
228     mediacontrol_PlaylistSeq* ps;
229
230     ps =( mediacontrol_PlaylistSeq* )malloc( sizeof( mediacontrol_PlaylistSeq ) );
231     if( ! ps )
232         return NULL;
233
234     ps->size = size;
235     ps->data = ( char** )malloc( size * sizeof( char* ) );
236     return ps;
237 }
238
239 void
240 mediacontrol_PlaylistSeq__free( mediacontrol_PlaylistSeq* ps )
241 {
242     if( ps )
243     {
244         int i;
245         for( i = 0 ; i < ps->size ; i++ )
246             free( ps->data[i] );
247     }
248     free( ps->data );
249     free( ps );
250 }
251
252 mediacontrol_Exception*
253 mediacontrol_exception_init( mediacontrol_Exception *exception )
254 {
255     if( exception == NULL )
256     {
257         exception = ( mediacontrol_Exception* )malloc( sizeof( mediacontrol_Exception ) );
258     }
259
260     exception->code = 0;
261     exception->message = NULL;
262     return exception;
263 }
264
265 void
266 mediacontrol_exception_free( mediacontrol_Exception *exception )
267 {
268     if( ! exception )
269         return;
270
271     free( exception->message );
272     free( exception );
273 }
274
275 mediacontrol_RGBPicture*
276 _mediacontrol_createRGBPicture( int i_width, int i_height, long i_chroma, long long l_date,
277                                 char* p_data, int i_datasize )
278 {
279     mediacontrol_RGBPicture *retval;
280
281     retval = mediacontrol_RGBPicture__alloc( i_datasize );
282     if( retval )
283     {
284         retval->width  = i_width;
285         retval->height = i_height;
286         retval->type   = i_chroma;
287         retval->date   = l_date;
288         retval->size   = i_datasize;
289         memcpy( retval->data, p_data, i_datasize );
290     }
291     return retval;
292 }