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