hd1000v.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:13k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * hd1000v.cpp: HD1000 video output display method
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: hd1000v.cpp 6961 2004-03-05 17:34:23Z jpsaman $
  6.  *
  7.  * Authors: Jean-Paul Saman <jpsaman@wxs.nl>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. extern "C" {
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #include <stdlib.h>                                                /* free() */
  29. #include <string.h>                                            /* strerror() */
  30. #include <vlc/vlc.h>
  31. #include <vlc/vout.h>
  32. #include <vlc/intf.h>
  33. }
  34. #include <cascade/graphics/CascadeBitmap.h>
  35. #include <cascade/graphics/CascadeScreen.h>
  36. /*****************************************************************************
  37.  * Local prototypes
  38.  *****************************************************************************/
  39. static int  Create    ( vlc_object_t * );
  40. static void Destroy   ( vlc_object_t * );
  41. static int  Init      ( vout_thread_t * );
  42. static void End       ( vout_thread_t * );
  43. static void Display   ( vout_thread_t *, picture_t * );
  44. static int NewPicture ( vout_thread_t *, picture_t * );
  45. static void FreePicture( vout_thread_t *, picture_t * );
  46. /*****************************************************************************
  47.  * Module descriptor
  48.  *****************************************************************************/
  49. vlc_module_begin();
  50.     set_description( _("HD1000 video output") );
  51.     set_capability( "video output", 100 );
  52.     add_shortcut( "hd1000v" );
  53.     set_callbacks( Create, Destroy );
  54. vlc_module_end();
  55. /*****************************************************************************
  56.  * vout_sys_t: video output method descriptor
  57.  *****************************************************************************
  58.  * This structure is part of the video output thread descriptor.
  59.  * It describes the aa specific properties of an output thread.
  60.  *****************************************************************************/
  61. struct vout_sys_t
  62. {
  63.     uint32_t            i_width;                     /* width of main window */
  64.     uint32_t            i_height;                   /* height of main window */
  65.     uint32_t            i_screen_depth;
  66.     vlc_bool_t          b_double_buffered;
  67.     
  68.     uint32_t            u_current; /* Current output resolution. */
  69.     CascadeScreen      *p_screen;
  70. };
  71. struct picture_sys_t
  72. {
  73.     CascadeSharedMemZone *p_image;
  74. };
  75. /*****************************************************************************
  76.  * Create: allocates video thread output method
  77.  *****************************************************************************
  78.  * This function allocates and initializes a aa vout method.
  79.  *****************************************************************************/
  80. static int Create( vlc_object_t *p_this )
  81. {
  82.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  83.     bool b_double_buffered = false;
  84.     
  85.     p_vout->p_sys = (struct vout_sys_t*) malloc( sizeof(struct vout_sys_t) );
  86.     if( p_vout->p_sys == NULL )
  87.     {
  88.         msg_Err( p_vout, "out of memory" );
  89.         return VLC_EGENERIC;
  90.     }
  91.     /* Allocate a screen for VLC vout. */
  92.     p_vout->p_sys->p_screen = new CascadeScreen();
  93.     if( p_vout->p_sys->p_screen == NULL )
  94.     {
  95.         msg_Err( p_vout, "unable to allocate screen" );
  96.         free( p_vout->p_sys );
  97.         return VLC_EGENERIC;
  98.     }
  99.     p_vout->pf_init = Init;
  100.     p_vout->pf_end = End;
  101.     p_vout->pf_manage = NULL;
  102.     p_vout->pf_render = NULL;
  103.     p_vout->pf_display = Display;
  104.     /* Get current screen resolution */
  105.     msg_Dbg( p_vout, "number of screen resolutions supported %u",
  106.       p_vout->p_sys->p_screen->GetNumScreenResolutionsSupported() );
  107.       
  108.     p_vout->p_sys->p_screen->GetCurrentScreenResolution( (u32) p_vout->p_sys->u_current );
  109.     p_vout->p_sys->p_screen->SetScreenResolution( (u32) p_vout->p_sys->u_current );
  110. #if 1
  111.     msg_Dbg( p_vout, "available screen resolutions:" );
  112.     for (u32 i=0; i<p_vout->p_sys->p_screen->GetNumScreenResolutionsSupported(); i++)
  113.     {
  114.         u32 i_width=0; 
  115. u32 i_height=0; 
  116. u8 i_screen_depth=0; 
  117. bool b_buffered;
  118.         p_vout->p_sys->p_screen->GetSupportedScreenResolutionAt( i,
  119.             i_width, i_height, i_screen_depth, b_buffered);
  120.         msg_Dbg( p_vout, "  screen index = %u, width = %u, height = %u, depth = %u, double buffered = %s",
  121.             i, i_width, i_height, i_screen_depth, (b_buffered ? "yes" : "no") );
  122.     }
  123. #endif        
  124.     
  125.     p_vout->p_sys->p_screen->GetSupportedScreenResolutionAt( (u32) p_vout->p_sys->u_current,
  126.             (u32) p_vout->p_sys->i_width,
  127.             (u32) p_vout->p_sys->i_height,
  128.             (u8) p_vout->p_sys->i_screen_depth,
  129.             b_double_buffered );
  130.     p_vout->p_sys->b_double_buffered = (vlc_bool_t) b_double_buffered;
  131.     msg_Dbg( p_vout, "using screen index = %u, width = %u, height = %u, depth = %u, double buffered = %d",
  132.             p_vout->p_sys->u_current, /* Current screen. */
  133.             p_vout->p_sys->i_width,
  134.             p_vout->p_sys->i_height,
  135.             p_vout->p_sys->i_screen_depth,
  136.             p_vout->p_sys->b_double_buffered );
  137.         
  138.     return VLC_SUCCESS;
  139. }
  140. static void Destroy( vlc_object_t *p_this )
  141. {
  142.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  143.     delete p_vout->p_sys->p_screen;
  144.     free( p_vout->p_sys );
  145. }
  146. /*****************************************************************************
  147.  * Init: initialize video thread output method
  148.  *****************************************************************************/
  149. static int Init( vout_thread_t *p_vout )
  150. {
  151.     int i_index;
  152.     picture_t *p_pic = NULL;
  153.     I_OUTPUTPICTURES = 0;
  154.     p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
  155.     p_vout->output.i_width = p_vout->p_sys->i_width;
  156.     p_vout->output.i_height = p_vout->p_sys->i_height;
  157.     p_vout->output.i_aspect = p_vout->p_sys->i_width
  158.                                * VOUT_ASPECT_FACTOR / p_vout->p_sys->i_height;
  159.     /* Only RGBA 32bpp is supported by output device. */
  160.     switch( p_vout->p_sys->i_screen_depth )
  161.     {
  162.         case 8: /* FIXME: set the palette */
  163.             p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); break;
  164.         case 15:
  165.             p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); break;
  166.         case 16:
  167.             p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); break;
  168.         case 24:
  169.             p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); break;
  170.         case 32:
  171.             p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); break;
  172.         default:
  173.             msg_Err( p_vout, "unknown screen depth %i",
  174.                      p_vout->p_sys->i_screen_depth );
  175.             return VLC_SUCCESS;
  176.     }
  177.     /* Find an empty picture slot */
  178.     for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
  179.     {
  180.         if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
  181.         {
  182.             p_pic = p_vout->p_picture + i_index;
  183.             break;
  184.         }
  185.     }
  186.     if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
  187.     {
  188.         return -1;
  189.     }
  190.     /* Allocate the picture */
  191.     p_pic->p->i_lines = p_vout->p_sys->i_height;
  192.     p_pic->p->i_visible_lines = p_vout->p_sys->i_height;
  193.     p_pic->p->i_pitch = p_vout->p_sys->i_width;
  194.     p_pic->p->i_pixel_pitch = 1;
  195.     p_pic->p->i_visible_pitch = p_vout->p_sys->i_width;
  196.     p_pic->i_planes = 1;
  197.     p_pic->i_status = DESTROYED_PICTURE;
  198.     p_pic->i_type   = DIRECT_PICTURE;
  199.     PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
  200.     I_OUTPUTPICTURES++;
  201.     return VLC_SUCCESS;
  202. }
  203. /*****************************************************************************
  204.  * End: terminate video thread output method
  205.  *****************************************************************************/
  206. static void End( vout_thread_t *p_vout )
  207. {
  208.     int i_index;
  209.     /* Free the direct buffers we allocated */
  210.     for( i_index = I_OUTPUTPICTURES ; i_index ; )
  211.     {
  212.         i_index--;
  213.         FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] );
  214.     }
  215. }
  216. /*****************************************************************************
  217.  * NewPicture: Allocate shared memory zone for video output
  218.  *****************************************************************************/
  219. static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
  220. {
  221.     CascadeDims p_dims = p_vout->p_sys->p_screen->GetDims();
  222.     p_pic->p_sys = (picture_sys_t *) malloc( sizeof( picture_sys_t ) );
  223.     if( p_pic->p_sys == NULL )
  224.     {
  225.         return -1;
  226.     }
  227.     /* Fill in picture_t fields */
  228.     vout_InitPicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
  229.                       p_vout->output.i_width, p_vout->output.i_height,
  230.                       p_vout->output.i_aspect );
  231.     p_pic->p_sys->p_image = new CascadeSharedMemZone();
  232.     if( p_pic->p_sys->p_image == NULL )
  233.     {
  234.         free( p_pic->p_sys );
  235.         return -1;
  236.     }
  237.     if( p_pic->p_sys->p_image->Open( "vlc_hd1000v", p_vout->output.i_width *
  238.             p_vout->output.i_height * p_vout->p_sys->i_screen_depth,
  239.             true ) )
  240.     {
  241.         msg_Err( p_vout, "failed to allocate shared memory" );
  242.         free( p_pic->p_sys );
  243.         return -1;
  244.     }
  245.     
  246.     p_pic->p->i_lines = p_vout->output.i_height;
  247.     p_pic->p->i_visible_lines = p_vout->output.i_height;
  248.     p_pic->p->p_pixels = (uint8_t*) p_pic->p_sys->p_image->MapLock();
  249.     p_pic->p->i_pitch = p_vout->p_sys->i_screen_depth;
  250.     p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch
  251.                                  * p_vout->output.i_width;
  252.     return VLC_SUCCESS;                                 
  253. }
  254. /*****************************************************************************
  255.  * FreePicture: destroy a picture allocated with NewPicture
  256.  *****************************************************************************
  257.  * Destroy SharedMemZoned AND associated data. The picture normally will be
  258.  * unlocked in the Display() function except when the video output is closed
  259.  * before the picture is displayed.
  260.  *****************************************************************************/
  261. static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic )
  262. {
  263.     if( p_pic->p_sys->p_image->Unlock() )
  264.     { /* Just a test to see the effect described above. REMOVE THIS */
  265.         msg_Err( p_vout, "unlocking shared memory failed, already unlocked" );
  266.     }
  267.     
  268.     if( p_pic->p_sys->p_image->Close() )
  269.     {
  270.         msg_Err( p_vout, "closing shared memory failed. Leaking memory of %ul",
  271.                     p_pic->p_sys->p_image->GetSize() );
  272.     }
  273.     
  274.     delete p_pic->p_sys->p_image;
  275.     free( p_pic->p_sys );
  276. }
  277. /*****************************************************************************
  278.  * Display: Map p_image onto the screen
  279.  *****************************************************************************/
  280. static void Display( vout_thread_t *p_vout, picture_t *p_pic )
  281. {
  282.     uint32_t i_width, i_height, i_x, i_y;
  283.     uint32_t i_offset = 0;
  284.     
  285.     vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
  286.                        p_vout->p_sys->i_height,
  287.                        &i_x, &i_y, &i_width, &i_height );
  288.     msg_Dbg( p_vout, "PlacePicture at x_left = %d, y_left = %d, x_bottom = %d, y_bottom = %d",
  289.                 i_x, i_y, i_width, i_height );
  290.     /* Currently the only pixel format supported is 32bpp RGBA.*/
  291.     p_vout->p_sys->p_screen->LockScreen();
  292.     
  293.     /* Unlock the shared memory region first. */
  294.     if( p_pic->p_sys->p_image->Unlock() ) 
  295.     {
  296.         msg_Err( p_vout, "unlocking shared memory failed. Expect threading problems." );
  297.     }
  298.     
  299.     p_vout->p_sys->p_screen->Blit( CascadePoint( (u32) i_x, (u32) i_y ), /* Place bitmap at */
  300.             (*p_pic->p_sys->p_image)   ,                                      /* Image data */
  301.             (u32) i_offset,                                   /* Offset in SharedMemoryZone */
  302.             (u32) i_width,                                           /* Source bitmap width */
  303.             (u32) i_height,                                         /* Source bitmap height */
  304.             (u32) p_vout->p_sys->i_screen_depth,                      /* Source pixel depth */
  305.             CascadeRect( (u32) i_x, (u32) i_y, (u32) i_width, (u32) i_height ) );
  306.             
  307.     p_vout->p_sys->p_screen->UnlockScreen();
  308. }