00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "plugin.h"
00032 #include "main.h"
00033 #include "PCM.h"
00034 #include "video_init.h"
00035 #include <GL/glu.h>
00036
00037 #include <vlc/input.h>
00038 #include <vlc/vout.h>
00039 #include "aout_internal.h"
00040
00041
00042
00043
00044 static int Open ( vlc_object_t * );
00045 static void Close ( vlc_object_t * );
00046
00047 vlc_module_begin();
00048 set_description( _("GaLaktos visualization plugin") );
00049 set_capability( "visualization", 0 );
00050 set_callbacks( Open, Close );
00051 add_shortcut( "galaktos" );
00052 vlc_module_end();
00053
00054
00055
00056
00057 typedef struct aout_filter_sys_t
00058 {
00059 galaktos_thread_t *p_thread;
00060
00061 } aout_filter_sys_t;
00062
00063 static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
00064 aout_buffer_t * );
00065
00066 static void Thread ( vlc_object_t * );
00067
00068 static char *TitleGet( vlc_object_t * );
00069
00070
00071 extern GLuint RenderTargetTextureID;
00072
00073
00074
00075
00076 static int Open( vlc_object_t *p_this )
00077 {
00078 aout_filter_t *p_filter = (aout_filter_t *)p_this;
00079 aout_filter_sys_t *p_sys;
00080 galaktos_thread_t *p_thread;
00081
00082 if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' )
00083 || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
00084 {
00085 msg_Warn( p_filter, "Bad input or output format" );
00086 return VLC_EGENERIC;
00087 }
00088 if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
00089 {
00090 msg_Warn( p_filter, "input and output formats are not similar" );
00091 return VLC_EGENERIC;
00092 }
00093
00094 p_filter->pf_do_work = DoWork;
00095 p_filter->b_in_place = 1;
00096
00097
00098 p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) );
00099
00100
00101 p_sys->p_thread = p_thread =
00102 vlc_object_create( p_filter, sizeof( galaktos_thread_t ) );
00103 vlc_object_attach( p_thread, p_this );
00104
00105
00106
00107
00108
00109
00110
00111 p_thread->i_cur_sample = 0;
00112 bzero( p_thread->p_data, 2*2*512 );
00113
00114 p_thread->i_width = 600;
00115 p_thread->i_height = 600;
00116 p_thread->b_fullscreen = 0;
00117 galaktos_init( p_thread );
00118
00119 p_thread->i_channels = aout_FormatNbChannels( &p_filter->input );
00120
00121 p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) );
00122
00123 if( vlc_thread_create( p_thread, "galaktos update thread", Thread,
00124 VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
00125 {
00126 msg_Err( p_filter, "cannot lauch galaktos thread" );
00127 if( p_thread->psz_title ) free( p_thread->psz_title );
00128 vlc_object_detach( p_thread );
00129 vlc_object_destroy( p_thread );
00130 free( p_sys );
00131 return VLC_EGENERIC;
00132 }
00133
00134 return VLC_SUCCESS;
00135 }
00136
00137
00138
00139
00140 static inline int16_t FloatToInt16( float f )
00141 {
00142 if( f >= 1.0 )
00143 return 32767;
00144 else if( f < -1.0 )
00145 return -32768;
00146 else
00147 return (int16_t)( f * 32768.0 );
00148 }
00149
00150
00151
00152
00153
00154
00155 static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
00156 aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
00157 {
00158 int i_samples;
00159 int i_channels;
00160 float *p_float;
00161 galaktos_thread_t *p_thread = p_filter->p_sys->p_thread;
00162
00163 p_float = (float *)p_in_buf->p_buffer;
00164 i_channels = p_thread->i_channels;
00165
00166 p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
00167 p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes;
00168
00169 for( i_samples = p_in_buf->i_nb_samples; i_samples > 0; i_samples-- )
00170 {
00171 int i_cur_sample = p_thread->i_cur_sample;
00172
00173 p_thread->p_data[0][i_cur_sample] = FloatToInt16( p_float[0] );
00174 if( i_channels > 1 )
00175 {
00176 p_thread->p_data[1][i_cur_sample] = FloatToInt16( p_float[1] );
00177 }
00178 p_float += i_channels;
00179
00180 if( ++(p_thread->i_cur_sample) == 512 )
00181 {
00182 addPCM( p_thread->p_data );
00183 p_thread->i_cur_sample = 0;
00184 }
00185 }
00186 }
00187
00188
00189
00190
00191 static void Thread( vlc_object_t *p_this )
00192 {
00193 galaktos_thread_t *p_thread = (galaktos_thread_t*)p_this;
00194
00195 int count=0;
00196 double realfps=0,fpsstart=0;
00197 int timed=0;
00198 int timestart=0;
00199 int mspf=0;
00200
00201
00202 p_thread->p_opengl =
00203 (vout_thread_t *)vlc_object_create( p_this, VLC_OBJECT_OPENGL );
00204 if( p_thread->p_opengl == NULL )
00205 {
00206 msg_Err( p_thread, "out of memory" );
00207 return;
00208 }
00209 vlc_object_attach( p_thread->p_opengl, p_this );
00210
00211 p_thread->p_opengl->i_window_width = p_thread->i_width;
00212 p_thread->p_opengl->i_window_height = p_thread->i_height;
00213 p_thread->p_opengl->render.i_width = p_thread->i_width;
00214 p_thread->p_opengl->render.i_height = p_thread->i_width;
00215 p_thread->p_opengl->render.i_aspect = VOUT_ASPECT_FACTOR;
00216 p_thread->p_opengl->b_scale = VLC_TRUE;
00217
00218 p_thread->p_module =
00219 module_Need( p_thread->p_opengl, "opengl provider", NULL, 0 );
00220 if( p_thread->p_module == NULL )
00221 {
00222 msg_Err( p_thread, "No OpenGL provider found" );
00223 vlc_object_detach( p_thread->p_opengl );
00224 vlc_object_destroy( p_thread->p_opengl );
00225 return;
00226 }
00227
00228 p_thread->p_opengl->pf_init( p_thread->p_opengl );
00229
00230 setup_opengl( p_thread->i_width, p_thread->i_height );
00231 CreateRenderTarget(512, &RenderTargetTextureID, NULL);
00232
00233 timestart=mdate()/1000;
00234
00235 while( !p_thread->b_die )
00236 {
00237 mspf = 1000 / 60;
00238 if( galaktos_update( p_thread ) == 1 )
00239 {
00240 p_thread->b_die = 1;
00241 }
00242 if( p_thread->psz_title )
00243 {
00244 free( p_thread->psz_title );
00245 p_thread->psz_title = NULL;
00246 }
00247
00248 if (++count%100==0)
00249 {
00250 realfps=100/((mdate()/1000-fpsstart)/1000);
00251
00252 fpsstart=mdate()/1000;
00253 }
00254
00255 timed=mspf-(mdate()/1000-timestart);
00256
00257 if (timed>0) msleep(1000*timed);
00258
00259 timestart=mdate()/1000;
00260 }
00261
00262
00263 module_Unneed( p_thread->p_opengl, p_thread->p_module );
00264 vlc_object_detach( p_thread->p_opengl );
00265 vlc_object_destroy( p_thread->p_opengl );
00266 }
00267
00268
00269
00270
00271 static void Close( vlc_object_t *p_this )
00272 {
00273 aout_filter_t *p_filter = (aout_filter_t *)p_this;
00274 aout_filter_sys_t *p_sys = p_filter->p_sys;
00275
00276
00277 p_sys->p_thread->b_die = VLC_TRUE;
00278
00279 galaktos_done( p_sys->p_thread );
00280
00281 vlc_thread_join( p_sys->p_thread );
00282
00283
00284 vlc_object_detach( p_sys->p_thread );
00285 vlc_object_destroy( p_sys->p_thread );
00286
00287 free( p_sys );
00288 }
00289
00290 static char *TitleGet( vlc_object_t *p_this )
00291 {
00292 char *psz_title = NULL;
00293 input_thread_t *p_input =
00294 vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_ANYWHERE );
00295
00296 if( p_input )
00297 {
00298 char *psz = strrchr( p_input->input.p_item->psz_uri, '/' );
00299
00300 if( psz )
00301 {
00302 psz++;
00303 }
00304 else
00305 {
00306 psz = p_input->input.p_item->psz_uri;
00307 }
00308 if( psz && *psz )
00309 {
00310 psz_title = strdup( psz );
00311 }
00312 vlc_object_release( p_input );
00313 }
00314
00315 return psz_title;
00316 }