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

hd1000v.cpp

00001 /*****************************************************************************
00002  * hd1000v.cpp: HD1000 video output display method
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: hd1000v.cpp 6961 2004-03-05 17:34:23Z jpsaman $
00006  *
00007  * Authors: Jean-Paul Saman <[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 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 extern "C" {
00028 #include <errno.h>                                                 /* ENOMEM */
00029 #include <stdlib.h>                                                /* free() */
00030 #include <string.h>                                            /* strerror() */
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  * Local prototypes
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  * Module descriptor
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  * vout_sys_t: video output method descriptor
00065  *****************************************************************************
00066  * This structure is part of the video output thread descriptor.
00067  * It describes the aa specific properties of an output thread.
00068  *****************************************************************************/
00069 struct vout_sys_t
00070 {
00071     uint32_t            i_width;                     /* width of main window */
00072     uint32_t            i_height;                   /* height of main window */
00073     uint32_t            i_screen_depth;
00074     vlc_bool_t          b_double_buffered;
00075     
00076     uint32_t            u_current; /* Current output resolution. */
00077     CascadeScreen      *p_screen;
00078 };
00079 
00080 struct picture_sys_t
00081 {
00082     CascadeSharedMemZone *p_image;
00083 };
00084 
00085 /*****************************************************************************
00086  * Create: allocates video thread output method
00087  *****************************************************************************
00088  * This function allocates and initializes a aa vout method.
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     /* Allocate a screen for VLC vout. */
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     /* Get current screen resolution */
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, /* Current screen. */
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  * Init: initialize video thread output method
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     /* Only RGBA 32bpp is supported by output device. */
00181     switch( p_vout->p_sys->i_screen_depth )
00182     {
00183         case 8: /* FIXME: set the palette */
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     /* Find an empty picture slot */
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     /* Allocate the picture */
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  * End: terminate video thread output method
00233  *****************************************************************************/
00234 static void End( vout_thread_t *p_vout )
00235 {
00236     int i_index;
00237 
00238     /* Free the direct buffers we allocated */
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  * NewPicture: Allocate shared memory zone for video output
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     /* Fill in picture_t fields */
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  * FreePicture: destroy a picture allocated with NewPicture
00292  *****************************************************************************
00293  * Destroy SharedMemZoned AND associated data. The picture normally will be
00294  * unlocked in the Display() function except when the video output is closed
00295  * before the picture is displayed.
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     { /* Just a test to see the effect described above. REMOVE THIS */
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  * Display: Map p_image onto the screen
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     /* Currently the only pixel format supported is 32bpp RGBA.*/
00329     p_vout->p_sys->p_screen->LockScreen();
00330     
00331     /* Unlock the shared memory region first. */
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 ), /* Place bitmap at */
00338             (*p_pic->p_sys->p_image)   ,                                      /* Image data */
00339             (u32) i_offset,                                   /* Offset in SharedMemoryZone */
00340             (u32) i_width,                                           /* Source bitmap width */
00341             (u32) i_height,                                         /* Source bitmap height */
00342             (u32) p_vout->p_sys->i_screen_depth,                      /* Source pixel 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 }

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