directfb.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * directfb.c: DirectFB video output display method
  3.  *****************************************************************************
  4.  * Copyright (C) 2005-2009 the VideoLAN team
  5.  *
  6.  * Authors: Iuri Diniz <iuri@digizap.com.br>
  7.  *
  8.  * This code is based in sdl.c and fb.c, thanks for VideoLAN team.
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #ifdef HAVE_CONFIG_H
  29. # include "config.h"
  30. #endif
  31. #include <vlc_common.h>
  32. #include <vlc_plugin.h>
  33. #include <vlc_vout.h>
  34. #include <directfb.h>
  35. /*****************************************************************************
  36.  * Local prototypes
  37.  *****************************************************************************/
  38. static int  Create    ( vlc_object_t * );
  39. static void Destroy   ( vlc_object_t * );
  40. static int  Init      ( vout_thread_t * );
  41. static void End       ( vout_thread_t * );
  42. static int  Manage    ( vout_thread_t * );
  43. static void Display   ( vout_thread_t *, picture_t * );
  44. static int  OpenDisplay    ( vout_thread_t * );
  45. static void CloseDisplay   ( vout_thread_t * );
  46. struct vout_sys_t
  47. {
  48.     IDirectFB *p_directfb;
  49.     IDirectFBSurface *p_primary;
  50.     DFBSurfacePixelFormat p_pixel_format;
  51.     int i_width;
  52.     int i_height;
  53.     uint8_t* p_pixels;
  54. };
  55. /*****************************************************************************
  56.  * Module descriptor
  57.  *****************************************************************************/
  58. vlc_module_begin ()
  59.     set_shortname( "DirectFB" )
  60.     set_category( CAT_VIDEO )
  61.     set_subcategory( SUBCAT_VIDEO_VOUT )
  62.     set_description( N_("DirectFB video output http://www.directfb.org/") )
  63.     set_capability( "video output", 60 )
  64.     add_shortcut( "directfb" )
  65.     set_callbacks( Create, Destroy )
  66. vlc_module_end ()
  67. static int Create( vlc_object_t *p_this )
  68. {
  69.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  70.     vout_sys_t *p_sys = NULL;
  71.     p_vout->pf_init = Init;
  72.     p_vout->pf_end = End;
  73.     p_vout->pf_manage = Manage;
  74.     p_vout->pf_render = NULL;
  75.     p_vout->pf_display = Display;
  76.     /* Allocate structure */
  77.     p_vout->p_sys = p_sys = malloc( sizeof( vout_sys_t ) );
  78.     if( !p_sys )
  79.         return VLC_ENOMEM;
  80.     p_sys->p_directfb = NULL;
  81.     p_sys->p_primary = NULL;
  82.     p_sys->p_pixels = NULL;
  83.     p_sys->i_width = 0;
  84.     p_sys->i_height = 0;
  85.     /* Init DirectFB */
  86.     if( DirectFBInit(NULL,NULL) != DFB_OK )
  87.     {
  88.         msg_Err(p_vout, "Cannot init DirectFB");
  89.         free( p_sys );
  90.         return VLC_EGENERIC;
  91.     }
  92.     if( OpenDisplay( p_vout ) )
  93.     {
  94.         msg_Err(p_vout, "Cannot create primary surface");
  95.         free( p_sys );
  96.         return VLC_EGENERIC;
  97.     }
  98.     return VLC_SUCCESS;
  99. }
  100. static int Init( vout_thread_t *p_vout )
  101. {
  102.     vout_sys_t *p_sys = p_vout->p_sys;
  103.     IDirectFBSurface *p_primary = (IDirectFBSurface *) p_vout->p_sys->p_primary;
  104.     uint8_t* p_pixels = NULL;
  105.     picture_t *p_pic = NULL;
  106.     int i_rlength, i_glength, i_blength;
  107.     int i_roffset, i_goffset, i_boffset;
  108.     int i_line_pitch;
  109.     int i_size;
  110.     int i_index;
  111.     I_OUTPUTPICTURES = 0;
  112.     switch( p_sys->p_pixel_format )
  113.     {
  114.         case DSPF_RGB332:
  115.             /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
  116.             /* i_pixel_pitch = 1; */
  117.             i_rlength = 3;
  118.             i_roffset = 5;
  119.             i_glength = 3;
  120.             i_goffset = 2;
  121.             i_blength = 2;
  122.             i_boffset = 0;
  123.             p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
  124.             break;
  125.         case DSPF_RGB16:
  126.             /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
  127.             /* i_pixel_pitch = 2; */
  128.             i_rlength = 5;
  129.             i_roffset = 11;
  130.             i_glength = 6;
  131.             i_goffset = 5;
  132.             i_blength = 5;
  133.             i_boffset = 0;
  134.             p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6');
  135.             break;
  136.         case DSPF_RGB24:
  137.             /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
  138.             /* i_pixel_pitch = 3; */
  139.             i_rlength = 8;
  140.             i_roffset = 16;
  141.             i_glength = 8;
  142.             i_goffset = 8;
  143.             i_blength = 8;
  144.             i_boffset = 0;
  145.             p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4');
  146.             break;
  147.         case DSPF_RGB32:
  148.             /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
  149.             /* i_pixel_pitch = 4; */
  150.             i_rlength = 8;
  151.             i_roffset = 16;
  152.             i_glength = 8;
  153.             i_goffset = 8;
  154.             i_blength = 8;
  155.             i_boffset = 0;
  156.             p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
  157.             break;
  158.         default:
  159.             msg_Err( p_vout, "unknown screen depth %i",
  160.                      p_sys->p_pixel_format );
  161.             return VLC_EGENERIC;
  162.     }
  163.     /* Set the RGB masks */
  164.     p_vout->output.i_rmask = ( (1 << i_rlength) - 1 ) << i_roffset;
  165.     p_vout->output.i_gmask = ( (1 << i_glength) - 1 ) << i_goffset;
  166.     p_vout->output.i_bmask = ( (1 << i_blength) - 1 ) << i_boffset;
  167.     /* Width and height */
  168.     p_vout->output.i_width  = p_sys->i_width;
  169.     p_vout->output.i_height = p_sys->i_height;
  170.     /* The aspect */
  171.     p_vout->output.i_aspect = (p_sys->i_width * VOUT_ASPECT_FACTOR) /
  172.                                p_sys->i_height;
  173.     /* Try to initialize 1 buffer */
  174.     /* Find an empty picture slot */
  175.     for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
  176.     {
  177.         if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
  178.         {
  179.             p_pic = p_vout->p_picture + i_index;
  180.             break;
  181.         }
  182.     }
  183.     /* Allocate the picture */
  184.     if( !p_pic )
  185.         return VLC_EGENERIC;
  186.     /* get the pixels */
  187.     if( p_primary->Lock( p_primary, DSLF_READ, (void **) &p_pixels,
  188.                          &i_line_pitch) != DFB_OK )
  189.         return VLC_EGENERIC;
  190.     /* allocate p_pixels */
  191.     i_size = i_line_pitch * p_sys->i_height;
  192.     p_sys->p_pixels = malloc( i_size );
  193.     if( p_sys->p_pixels == NULL )
  194.     {
  195.         p_primary->Unlock(p_primary);
  196.         return VLC_ENOMEM;
  197.     }
  198.     /* copy pixels */
  199.     memcpy( p_sys->p_pixels,  p_pixels, i_size );
  200.     if( p_primary->Unlock(p_primary) != DFB_OK )
  201.     {
  202.         return VLC_EGENERIC;
  203.     }
  204.     p_pic->p->p_pixels = p_sys->p_pixels;
  205.     p_pic->p->i_pixel_pitch = i_line_pitch / p_sys->i_width;
  206.     p_pic->p->i_lines = p_sys->i_height;
  207.     p_pic->p->i_visible_lines = p_sys->i_height;
  208.     p_pic->p->i_pitch = i_line_pitch;
  209.     p_pic->p->i_visible_pitch = i_line_pitch;
  210.     p_pic->i_planes = 1;
  211.     p_pic->i_status = DESTROYED_PICTURE;
  212.     p_pic->i_type   = DIRECT_PICTURE;
  213.     PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
  214.     I_OUTPUTPICTURES++;
  215.     return VLC_SUCCESS;
  216. }
  217. static void End( vout_thread_t *p_vout )
  218. {
  219.     vout_sys_t *p_sys = p_vout->p_sys;
  220.     free( p_sys->p_pixels );
  221. }
  222. static void Destroy( vlc_object_t *p_this )
  223. {
  224.     vout_thread_t *p_vout = (vout_thread_t *)p_this;
  225.     vout_sys_t *p_sys = p_vout->p_sys;
  226.     CloseDisplay( p_vout );
  227.     free( p_sys );
  228.     p_sys = NULL;
  229. }
  230. static int Manage( vout_thread_t *p_vout )
  231. {
  232.     return VLC_SUCCESS;
  233. }
  234. static void Display( vout_thread_t *p_vout, picture_t *p_pic )
  235. {
  236.     vout_sys_t *p_sys = p_vout->p_sys;
  237.     IDirectFBSurface *p_primary = (IDirectFBSurface *) p_sys->p_primary;
  238.     uint8_t* p_pixels = NULL;
  239.     int i_size;
  240.     int i_line_pitch;
  241.     /* get the pixels */
  242.     if( p_primary->Lock( p_primary, DSLF_WRITE,
  243.                          (void **) &p_pixels,
  244.                          &i_line_pitch) == DFB_OK )
  245.     {
  246.         i_size = i_line_pitch * p_vout->p_sys->i_height;
  247.         /* copy pixels */
  248.         memcpy( p_pixels, p_pic->p->p_pixels, i_size);
  249.         if( p_primary->Unlock(p_primary) == DFB_OK )
  250.         {
  251.             p_primary->Flip(p_primary, NULL, 0);
  252.         }
  253.     }
  254. }
  255. static int OpenDisplay( vout_thread_t *p_vout )
  256. {
  257.     vout_sys_t *p_sys = p_vout->p_sys;
  258.     IDirectFB *p_directfb = NULL;
  259.     IDirectFBSurface *p_primary = NULL;
  260.     DFBSurfaceDescription dsc;
  261.     /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/
  262.     dsc.flags = DSDESC_CAPS;
  263.     dsc.caps  = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
  264.     /*dsc.width = 352;*/
  265.     /*dsc.height = 240;*/
  266.     if( DirectFBCreate( &p_directfb ) != DFB_OK )
  267.         return VLC_EGENERIC;
  268.     p_sys->p_directfb = p_directfb;
  269.     if( !p_directfb )
  270.         return VLC_EGENERIC;
  271.     if( p_directfb->CreateSurface( p_directfb, &dsc, &p_primary ) )
  272.         return VLC_EGENERIC;
  273.     p_sys->p_primary = p_primary;
  274.     if( !p_primary )
  275.         return VLC_EGENERIC;
  276.     p_primary->GetSize( p_primary, &p_sys->i_width,
  277.                         &p_sys->i_height );
  278.     p_primary->GetPixelFormat( p_primary, &p_sys->p_pixel_format );
  279.     p_primary->FillRectangle( p_primary, 0, 0, p_sys->i_width,
  280.                               p_sys->i_height );
  281.     p_primary->Flip( p_primary, NULL, 0 );
  282.     return VLC_SUCCESS;
  283. }
  284. static void CloseDisplay( vout_thread_t *p_vout )
  285. {
  286.     vout_sys_t *p_sys = p_vout->p_sys;
  287.     IDirectFB *p_directfb = p_sys->p_directfb;
  288.     IDirectFBSurface *p_primary = p_sys->p_primary;
  289.     if( p_primary )
  290.         p_primary->Release( p_primary );
  291.     if( p_directfb )
  292.         p_directfb->Release( p_directfb );
  293. }