Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

audio_video.c

00001 /*****************************************************************************
00002  * audio_video.c: Audio/Video management : volume, snapshot, OSD
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  * $Id: vlc.c 10786 2005-04-23 23:19:17Z zorglub $
00006  *
00007  * Authors: Olivier Aubert <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
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>                                      /* malloc(), free() */
00040 #include <string.h>
00041 
00042 #include <errno.h>                                                 /* ENOMEM */
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        if( var_Get( self->p_vlc, "snapshot-id", &val ) == VLC_SUCCESS )
00081        p_vout = vlc_object_get( self->p_vlc, val.i_int );
00082     */
00083 
00084     /* FIXME: if in p_libvlc, we cannot have multiple video outputs */
00085     /* Once corrected, search for snapshot-id to modify all instances */
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     /* We test if the vout is a snapshot module. We cannot test
00101        pvout_psz_object_name( which is NULL ). But we can check if
00102        there are snapshot-specific variables */
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     /* Handle the a_position parameter */
00112     if( ! ( a_position->origin == mediacontrol_RelativePosition
00113             && a_position->value == 0 ) )
00114     {
00115         /* The position is not the current one. Go to it. */
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     /* FIXME: We should not go further until we got past the position
00127        ( which means that we had the possibility to capture the right
00128        picture ). */
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     /* Find the more appropriate picture, based on date */
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             /* This one is closer, and _after_ the requested position */
00159             p_best_snapshot = pointer[i_index];
00160         }
00161     }
00162 
00163     /* FIXME: add a test for the case that no picture matched the test
00164        ( we have p_best_snapshot == pointer[0] */
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     /* We test if the vout is a snapshot module. We cannot test
00206        pvout_psz_object_name( which is NULL ). But we can check if
00207        there are snapshot-specific variables */
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     /* Create a new subpicture region */
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         /* FIXME */
00358         /* i_now = input_ClockGetTS( p_input, NULL, 0 ); */
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 }

Generated on Tue Dec 20 10:14:59 2005 for vlc-0.8.4a by  doxygen 1.4.2