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 extern "C" {
00028 #include <errno.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031
00032 #include <vlc/vlc.h>
00033 #include <vlc/vout.h>
00034 #include <vlc/intf.h>
00035 }
00036
00037 #include <cascade/graphics/CascadeBitmap.h>
00038 #include <cascade/graphics/CascadeScreen.h>
00039
00040
00041
00042
00043 static int Create ( vlc_object_t * );
00044 static void Destroy ( vlc_object_t * );
00045
00046 static int Init ( vout_thread_t * );
00047 static void End ( vout_thread_t * );
00048 static void Display ( vout_thread_t *, picture_t * );
00049
00050 static int NewPicture ( vout_thread_t *, picture_t * );
00051 static void FreePicture( vout_thread_t *, picture_t * );
00052
00053
00054
00055
00056 vlc_module_begin();
00057 set_description( _("HD1000 video output") );
00058 set_capability( "video output", 100 );
00059 add_shortcut( "hd1000v" );
00060 set_callbacks( Create, Destroy );
00061 vlc_module_end();
00062
00063
00064
00065
00066
00067
00068
00069 struct vout_sys_t
00070 {
00071 uint32_t i_width;
00072 uint32_t i_height;
00073 uint32_t i_screen_depth;
00074 vlc_bool_t b_double_buffered;
00075
00076 uint32_t u_current;
00077 CascadeScreen *p_screen;
00078 };
00079
00080 struct picture_sys_t
00081 {
00082 CascadeSharedMemZone *p_image;
00083 };
00084
00085
00086
00087
00088
00089
00090 static int Create( vlc_object_t *p_this )
00091 {
00092 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00093 bool b_double_buffered = false;
00094
00095 p_vout->p_sys = (struct vout_sys_t*) malloc( sizeof(struct vout_sys_t) );
00096 if( p_vout->p_sys == NULL )
00097 {
00098 msg_Err( p_vout, "out of memory" );
00099 return VLC_EGENERIC;
00100 }
00101
00102
00103 p_vout->p_sys->p_screen = new CascadeScreen();
00104 if( p_vout->p_sys->p_screen == NULL )
00105 {
00106 msg_Err( p_vout, "unable to allocate screen" );
00107 free( p_vout->p_sys );
00108 return VLC_EGENERIC;
00109 }
00110
00111 p_vout->pf_init = Init;
00112 p_vout->pf_end = End;
00113 p_vout->pf_manage = NULL;
00114 p_vout->pf_render = NULL;
00115 p_vout->pf_display = Display;
00116
00117
00118 msg_Dbg( p_vout, "number of screen resolutions supported %u",
00119 p_vout->p_sys->p_screen->GetNumScreenResolutionsSupported() );
00120
00121 p_vout->p_sys->p_screen->GetCurrentScreenResolution( (u32) p_vout->p_sys->u_current );
00122 p_vout->p_sys->p_screen->SetScreenResolution( (u32) p_vout->p_sys->u_current );
00123
00124 #if 1
00125 msg_Dbg( p_vout, "available screen resolutions:" );
00126 for (u32 i=0; i<p_vout->p_sys->p_screen->GetNumScreenResolutionsSupported(); i++)
00127 {
00128 u32 i_width=0;
00129 u32 i_height=0;
00130 u8 i_screen_depth=0;
00131 bool b_buffered;
00132
00133 p_vout->p_sys->p_screen->GetSupportedScreenResolutionAt( i,
00134 i_width, i_height, i_screen_depth, b_buffered);
00135 msg_Dbg( p_vout, " screen index = %u, width = %u, height = %u, depth = %u, double buffered = %s",
00136 i, i_width, i_height, i_screen_depth, (b_buffered ? "yes" : "no") );
00137 }
00138 #endif
00139
00140 p_vout->p_sys->p_screen->GetSupportedScreenResolutionAt( (u32) p_vout->p_sys->u_current,
00141 (u32) p_vout->p_sys->i_width,
00142 (u32) p_vout->p_sys->i_height,
00143 (u8) p_vout->p_sys->i_screen_depth,
00144 b_double_buffered );
00145 p_vout->p_sys->b_double_buffered = (vlc_bool_t) b_double_buffered;
00146 msg_Dbg( p_vout, "using screen index = %u, width = %u, height = %u, depth = %u, double buffered = %d",
00147 p_vout->p_sys->u_current,
00148 p_vout->p_sys->i_width,
00149 p_vout->p_sys->i_height,
00150 p_vout->p_sys->i_screen_depth,
00151 p_vout->p_sys->b_double_buffered );
00152
00153 return VLC_SUCCESS;
00154 }
00155
00156 static void Destroy( vlc_object_t *p_this )
00157 {
00158 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00159
00160 delete p_vout->p_sys->p_screen;
00161 free( p_vout->p_sys );
00162 }
00163
00164
00165
00166
00167 static int Init( vout_thread_t *p_vout )
00168 {
00169 int i_index;
00170 picture_t *p_pic = NULL;
00171
00172 I_OUTPUTPICTURES = 0;
00173
00174 p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
00175 p_vout->output.i_width = p_vout->p_sys->i_width;
00176 p_vout->output.i_height = p_vout->p_sys->i_height;
00177 p_vout->output.i_aspect = p_vout->p_sys->i_width
00178 * VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
00179
00180
00181 switch( p_vout->p_sys->i_screen_depth )
00182 {
00183 case 8:
00184 p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); break;
00185 case 15:
00186 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); break;
00187 case 16:
00188 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); break;
00189 case 24:
00190 p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); break;
00191 case 32:
00192 p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); break;
00193 default:
00194 msg_Err( p_vout, "unknown screen depth %i",
00195 p_vout->p_sys->i_screen_depth );
00196 return VLC_SUCCESS;
00197 }
00198
00199
00200 for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
00201 {
00202 if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
00203 {
00204 p_pic = p_vout->p_picture + i_index;
00205 break;
00206 }
00207 }
00208
00209 if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
00210 {
00211 return -1;
00212 }
00213
00214
00215 p_pic->p->i_lines = p_vout->p_sys->i_height;
00216 p_pic->p->i_visible_lines = p_vout->p_sys->i_height;
00217 p_pic->p->i_pitch = p_vout->p_sys->i_width;
00218 p_pic->p->i_pixel_pitch = 1;
00219 p_pic->p->i_visible_pitch = p_vout->p_sys->i_width;
00220 p_pic->i_planes = 1;
00221
00222 p_pic->i_status = DESTROYED_PICTURE;
00223 p_pic->i_type = DIRECT_PICTURE;
00224
00225 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
00226 I_OUTPUTPICTURES++;
00227
00228 return VLC_SUCCESS;
00229 }
00230
00231
00232
00233
00234 static void End( vout_thread_t *p_vout )
00235 {
00236 int i_index;
00237
00238
00239 for( i_index = I_OUTPUTPICTURES ; i_index ; )
00240 {
00241 i_index--;
00242 FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] );
00243 }
00244 }
00245
00246
00247
00248
00249 static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
00250 {
00251 CascadeDims p_dims = p_vout->p_sys->p_screen->GetDims();
00252
00253 p_pic->p_sys = (picture_sys_t *) malloc( sizeof( picture_sys_t ) );
00254 if( p_pic->p_sys == NULL )
00255 {
00256 return -1;
00257 }
00258
00259
00260 vout_InitPicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
00261 p_vout->output.i_width, p_vout->output.i_height,
00262 p_vout->output.i_aspect );
00263
00264 p_pic->p_sys->p_image = new CascadeSharedMemZone();
00265 if( p_pic->p_sys->p_image == NULL )
00266 {
00267 free( p_pic->p_sys );
00268 return -1;
00269 }
00270
00271 if( p_pic->p_sys->p_image->Open( "vlc_hd1000v", p_vout->output.i_width *
00272 p_vout->output.i_height * p_vout->p_sys->i_screen_depth,
00273 true ) )
00274 {
00275 msg_Err( p_vout, "failed to allocate shared memory" );
00276 free( p_pic->p_sys );
00277 return -1;
00278 }
00279
00280 p_pic->p->i_lines = p_vout->output.i_height;
00281 p_pic->p->i_visible_lines = p_vout->output.i_height;
00282 p_pic->p->p_pixels = (uint8_t*) p_pic->p_sys->p_image->MapLock();
00283 p_pic->p->i_pitch = p_vout->p_sys->i_screen_depth;
00284 p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch
00285 * p_vout->output.i_width;
00286
00287 return VLC_SUCCESS;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297 static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic )
00298 {
00299 if( p_pic->p_sys->p_image->Unlock() )
00300 {
00301 msg_Err( p_vout, "unlocking shared memory failed, already unlocked" );
00302 }
00303
00304 if( p_pic->p_sys->p_image->Close() )
00305 {
00306 msg_Err( p_vout, "closing shared memory failed. Leaking memory of %ul",
00307 p_pic->p_sys->p_image->GetSize() );
00308 }
00309
00310 delete p_pic->p_sys->p_image;
00311 free( p_pic->p_sys );
00312 }
00313
00314
00315
00316
00317 static void Display( vout_thread_t *p_vout, picture_t *p_pic )
00318 {
00319 uint32_t i_width, i_height, i_x, i_y;
00320 uint32_t i_offset = 0;
00321
00322 vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
00323 p_vout->p_sys->i_height,
00324 &i_x, &i_y, &i_width, &i_height );
00325 msg_Dbg( p_vout, "PlacePicture at x_left = %d, y_left = %d, x_bottom = %d, y_bottom = %d",
00326 i_x, i_y, i_width, i_height );
00327
00328
00329 p_vout->p_sys->p_screen->LockScreen();
00330
00331
00332 if( p_pic->p_sys->p_image->Unlock() )
00333 {
00334 msg_Err( p_vout, "unlocking shared memory failed. Expect threading problems." );
00335 }
00336
00337 p_vout->p_sys->p_screen->Blit( CascadePoint( (u32) i_x, (u32) i_y ),
00338 (*p_pic->p_sys->p_image) ,
00339 (u32) i_offset,
00340 (u32) i_width,
00341 (u32) i_height,
00342 (u32) p_vout->p_sys->i_screen_depth,
00343 CascadeRect( (u32) i_x, (u32) i_y, (u32) i_width, (u32) i_height ) );
00344
00345 p_vout->p_sys->p_screen->UnlockScreen();
00346 }