00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <vlc/control.h>
00025
00026 #include <vlc/intf.h>
00027 #include <vlc/vout.h>
00028 #include <vlc/aout.h>
00029 #include <vlc_demux.h>
00030
00031 #include <vlc_osd.h>
00032
00033 #define HAS_SNAPSHOT 1
00034
00035 #ifdef HAS_SNAPSHOT
00036 #include <snapshot.h>
00037 #endif
00038
00039 #include <stdlib.h>
00040 #include <string.h>
00041
00042 #include <errno.h>
00043 #include <stdio.h>
00044 #include <ctype.h>
00045
00046 #ifdef HAVE_UNISTD_H
00047 # include <unistd.h>
00048 #endif
00049 #ifdef HAVE_SYS_TIME_H
00050 # include <sys/time.h>
00051 #endif
00052 #ifdef HAVE_SYS_TYPES_H
00053 # include <sys/types.h>
00054 #endif
00055
00056 #define RAISE( c, m ) exception->code = c; \
00057 exception->message = strdup(m);
00058
00059 mediacontrol_RGBPicture *
00060 mediacontrol_snapshot( mediacontrol_Instance *self,
00061 const mediacontrol_Position * a_position,
00062 mediacontrol_Exception *exception )
00063 {
00064 mediacontrol_RGBPicture *retval = NULL;
00065 input_thread_t* p_input = self->p_playlist->p_input;
00066 vout_thread_t *p_vout = NULL;
00067 int i_datasize;
00068 snapshot_t **pointer;
00069 vlc_value_t val;
00070 int i_index;
00071 snapshot_t *p_best_snapshot;
00072 long searched_date;
00073 #ifdef HAS_SNAPSHOT
00074 int i_cachesize;
00075 #endif
00076
00077 exception=mediacontrol_exception_init( exception );
00078
00079
00080
00081
00082
00083
00084
00085
00086 if( var_Get( p_input, "snapshot-id", &val ) != VLC_SUCCESS )
00087 {
00088 RAISE( mediacontrol_InternalException, "No snapshot-id in p_input" );
00089 return NULL;
00090 }
00091 p_vout = vlc_object_get( self->p_vlc, val.i_int );
00092
00093 if( ! p_vout )
00094 {
00095 RAISE( mediacontrol_InternalException, "No snapshot module" );
00096 return NULL;
00097 }
00098
00099 #ifdef HAS_SNAPSHOT
00100
00101
00102
00103 if( var_Get( p_vout, "snapshot-datasize", &val ) != VLC_SUCCESS )
00104 {
00105 RAISE( mediacontrol_InternalException, "No snapshot module" );
00106 vlc_object_release( p_vout );
00107 return NULL;
00108 }
00109 i_datasize = val.i_int;
00110
00111
00112 if( ! ( a_position->origin == mediacontrol_RelativePosition
00113 && a_position->value == 0 ) )
00114 {
00115
00116 mediacontrol_set_media_position( self,
00117 ( mediacontrol_Position* ) a_position,
00118 exception );
00119 if( exception->code )
00120 {
00121 vlc_object_release( p_vout );
00122 return NULL;
00123 }
00124 }
00125
00126
00127
00128
00129
00130 vlc_mutex_lock( &p_vout->picture_lock );
00131
00132 searched_date = mediacontrol_position2microsecond( p_input,
00133 ( mediacontrol_Position * ) a_position );
00134
00135 var_Get( p_vout, "snapshot-cache-size", &val );
00136 i_cachesize = val.i_int ;
00137
00138 var_Get( p_vout, "snapshot-list-pointer", &val );
00139 pointer = ( snapshot_t ** )val.p_address;
00140
00141 if( ! pointer )
00142 {
00143 RAISE( mediacontrol_InternalException, "No available snapshot" );
00144
00145 vlc_mutex_unlock( &p_vout->picture_lock );
00146 vlc_object_release( p_vout );
00147 return NULL;
00148 }
00149
00150
00151 p_best_snapshot = pointer[0];
00152
00153 for( i_index = 1 ; i_index < i_cachesize ; i_index++ )
00154 {
00155 long l_diff = pointer[i_index]->date - searched_date;
00156 if( l_diff > 0 && l_diff < abs( p_best_snapshot->date - searched_date ))
00157 {
00158
00159 p_best_snapshot = pointer[i_index];
00160 }
00161 }
00162
00163
00164
00165 retval = _mediacontrol_createRGBPicture( p_best_snapshot->i_width,
00166 p_best_snapshot->i_height,
00167 p_vout->output.i_chroma,
00168 p_best_snapshot->date,
00169 p_best_snapshot->p_data,
00170 i_datasize );
00171
00172 vlc_mutex_unlock( &p_vout->picture_lock );
00173 vlc_object_release( p_vout );
00174
00175 #endif
00176
00177 return retval;
00178 }
00179
00180 mediacontrol_RGBPicture **
00181 mediacontrol_all_snapshots( mediacontrol_Instance *self,
00182 mediacontrol_Exception *exception )
00183 {
00184 mediacontrol_RGBPicture **retval = NULL;
00185 vout_thread_t *p_vout = NULL;
00186 int i_datasize;
00187 int i_cachesize;
00188 vlc_value_t val;
00189 int i_index;
00190 #ifdef HAS_SNAPSHOT
00191 snapshot_t **pointer;
00192 #endif
00193
00194 exception=mediacontrol_exception_init( exception );
00195
00196 if( var_Get( self->p_playlist->p_input, "snapshot-id", &val ) == VLC_SUCCESS )
00197 p_vout = vlc_object_get( self->p_vlc, val.i_int );
00198
00199 if( ! p_vout )
00200 {
00201 RAISE( mediacontrol_InternalException, "No snapshot module" );
00202 return NULL;
00203 }
00204 #ifdef HAS_SNAPSHOT
00205
00206
00207
00208 if( var_Get( p_vout, "snapshot-datasize", &val ) != VLC_SUCCESS )
00209 {
00210 RAISE( mediacontrol_InternalException, "No snapshot module" );
00211 vlc_object_release( p_vout );
00212 return NULL;
00213 }
00214 i_datasize = val.i_int;
00215
00216 vlc_mutex_lock( &p_vout->picture_lock );
00217
00218 var_Get( p_vout, "snapshot-cache-size", &val );
00219 i_cachesize = val.i_int ;
00220
00221 var_Get( p_vout, "snapshot-list-pointer", &val );
00222 pointer = ( snapshot_t ** )val.p_address;
00223
00224 if( ! pointer )
00225 {
00226 RAISE( mediacontrol_InternalException, "No available picture" );
00227
00228 vlc_mutex_unlock( &p_vout->picture_lock );
00229 vlc_object_release( p_vout );
00230 return NULL;
00231 }
00232
00233 retval = ( mediacontrol_RGBPicture** )malloc( (i_cachesize + 1 ) * sizeof( char* ));
00234
00235 for( i_index = 0 ; i_index < i_cachesize ; i_index++ )
00236 {
00237 snapshot_t *p_s = pointer[i_index];
00238 mediacontrol_RGBPicture *p_rgb;
00239
00240 p_rgb = _mediacontrol_createRGBPicture( p_s->i_width,
00241 p_s->i_height,
00242 p_vout->output.i_chroma,
00243 p_s->date,
00244 p_s->p_data,
00245 i_datasize );
00246
00247 retval[i_index] = p_rgb;
00248 }
00249
00250 retval[i_cachesize] = NULL;
00251
00252 vlc_mutex_unlock( &p_vout->picture_lock );
00253 vlc_object_release( p_vout );
00254
00255 #endif
00256
00257 return retval;
00258 }
00259
00260 int mediacontrol_showtext( vout_thread_t *p_vout, int i_channel,
00261 char *psz_string, text_style_t *p_style,
00262 int i_flags, int i_hmargin, int i_vmargin,
00263 mtime_t i_start, mtime_t i_stop )
00264 {
00265 subpicture_t *p_spu;
00266 video_format_t fmt;
00267
00268 if( !psz_string ) return VLC_EGENERIC;
00269
00270 p_spu = spu_CreateSubpicture( p_vout->p_spu );
00271 if( !p_spu ) return VLC_EGENERIC;
00272
00273
00274 memset( &fmt, 0, sizeof(video_format_t) );
00275 fmt.i_chroma = VLC_FOURCC('T','E','X','T');
00276 fmt.i_aspect = 0;
00277 fmt.i_width = fmt.i_height = 0;
00278 fmt.i_x_offset = fmt.i_y_offset = 0;
00279 p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_vout), &fmt );
00280 if( !p_spu->p_region )
00281 {
00282 msg_Err( p_vout, "cannot allocate SPU region" );
00283 spu_DestroySubpicture( p_vout->p_spu, p_spu );
00284 return VLC_EGENERIC;
00285 }
00286
00287 p_spu->p_region->psz_text = strdup( psz_string );
00288 p_spu->i_start = i_start;
00289 p_spu->i_stop = i_stop;
00290 p_spu->b_ephemer = VLC_FALSE;
00291 p_spu->b_absolute = VLC_FALSE;
00292
00293 p_spu->i_x = i_hmargin;
00294 p_spu->i_y = i_vmargin;
00295 p_spu->i_flags = i_flags;
00296 p_spu->i_channel = i_channel;
00297
00298 spu_DisplaySubpicture( p_vout->p_spu, p_spu );
00299
00300 return VLC_SUCCESS;
00301 }
00302
00303
00304 void
00305 mediacontrol_display_text( mediacontrol_Instance *self,
00306 const char * message,
00307 const mediacontrol_Position * begin,
00308 const mediacontrol_Position * end,
00309 mediacontrol_Exception *exception )
00310 {
00311 input_thread_t *p_input = NULL;
00312 vout_thread_t *p_vout = NULL;
00313 char* psz_message;
00314
00315 psz_message = strdup( message );
00316 if( !psz_message )
00317 {
00318 RAISE( mediacontrol_InternalException, "No more memory" );
00319 return;
00320 }
00321
00322 p_vout = vlc_object_find( self->p_playlist, VLC_OBJECT_VOUT, FIND_CHILD );
00323 if( ! p_vout )
00324 {
00325 RAISE( mediacontrol_InternalException, "No video output" );
00326 return;
00327 }
00328
00329 if( begin->origin == mediacontrol_RelativePosition &&
00330 begin->value == 0 &&
00331 end->origin == mediacontrol_RelativePosition )
00332 {
00333 mtime_t i_duration = 0;
00334 mtime_t i_now = mdate();
00335
00336 i_duration = 1000 * mediacontrol_unit_convert( self->p_playlist->p_input,
00337 end->key,
00338 mediacontrol_MediaTime,
00339 end->value );
00340
00341 mediacontrol_showtext( p_vout, DEFAULT_CHAN, psz_message, NULL,
00342 OSD_ALIGN_BOTTOM | OSD_ALIGN_LEFT, 0, 0,
00343 i_now, i_now + i_duration );
00344 }
00345 else
00346 {
00347 mtime_t i_debut, i_fin, i_now;
00348
00349 p_input = self->p_playlist->p_input;
00350 if( ! p_input )
00351 {
00352 RAISE( mediacontrol_InternalException, "No input" );
00353 vlc_object_release( p_vout );
00354 return;
00355 }
00356
00357
00358
00359 i_now = mdate();
00360
00361 i_debut = mediacontrol_position2microsecond( p_input,
00362 ( mediacontrol_Position* ) begin );
00363 i_debut += i_now;
00364
00365 i_fin = mediacontrol_position2microsecond( p_input,
00366 ( mediacontrol_Position * ) end );
00367 i_fin += i_now;
00368
00369 vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, psz_message, NULL,
00370 OSD_ALIGN_BOTTOM | OSD_ALIGN_LEFT, 0, 0,
00371 i_debut, i_fin );
00372 }
00373
00374 vlc_object_release( p_vout );
00375 }
00376
00377 unsigned short
00378 mediacontrol_sound_get_volume( mediacontrol_Instance *self,
00379 mediacontrol_Exception *exception )
00380 {
00381 short retval;
00382 audio_volume_t i_volume;
00383
00384 if( !self->p_intf )
00385 {
00386 RAISE( mediacontrol_InternalException, "No interface module" );
00387 return 0;
00388 }
00389 aout_VolumeGet( self->p_intf, &i_volume );
00390 retval = i_volume;
00391 return retval;
00392 }
00393
00394 void
00395 mediacontrol_sound_set_volume( mediacontrol_Instance *self,
00396 const unsigned short volume,
00397 mediacontrol_Exception *exception )
00398 {
00399 if( !self->p_intf )
00400 {
00401 RAISE( mediacontrol_InternalException, "No interface module" );
00402 return;
00403 }
00404 aout_VolumeSet( self->p_intf,( audio_volume_t )volume );
00405 }
00406
00407 vlc_bool_t mediacontrol_set_visual( mediacontrol_Instance *self,
00408 WINDOWHANDLE visual_id,
00409 mediacontrol_Exception *exception )
00410 {
00411 vlc_value_t value;
00412 int ret;
00413
00414 if( !self->p_vlc )
00415 {
00416 RAISE( mediacontrol_InternalException, "No vlc reference" );
00417 return 0;
00418 }
00419 value.i_int=visual_id;
00420 ret = var_Set(self->p_vlc, "drawable", value);
00421
00422 return (ret == VLC_SUCCESS);
00423 }