X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fdirectfb.c;h=fd18cbbe905f1378d8b8187f4f88579eced8b12f;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=77fa243a4adb2e8a3c7583f00a2a7b7dfbf1f689;hpb=7f12470415d98e9e0ac725f2bb96b5fa74ef27f1;p=vlc diff --git a/modules/video_output/directfb.c b/modules/video_output/directfb.c index 77fa243a4a..fd18cbbe90 100644 --- a/modules/video_output/directfb.c +++ b/modules/video_output/directfb.c @@ -25,323 +25,261 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* ENOMEM */ - #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include -#include +#include +#include + #include /***************************************************************************** - * Local prototypes + * Module descriptor *****************************************************************************/ -static int Create ( vlc_object_t * ); -static void Destroy ( vlc_object_t * ); - -static int Init ( vout_thread_t * ); -static void End ( vout_thread_t * ); -static int Manage ( vout_thread_t * ); -static void Display ( vout_thread_t *, picture_t * ); - -static int OpenDisplay ( vout_thread_t * ); -static void CloseDisplay ( vout_thread_t * ); - -struct vout_sys_t -{ - IDirectFB *p_directfb; - IDirectFBSurface *p_primary; - DFBSurfacePixelFormat p_pixel_format; - - int i_width; - int i_height; - - uint8_t* p_pixels; -}; +static int Open (vlc_object_t *); +static void Close(vlc_object_t *); + +vlc_module_begin() + set_shortname("DirectFB") + set_category(CAT_VIDEO) + set_subcategory(SUBCAT_VIDEO_VOUT) + set_description(N_("DirectFB video output http://www.directfb.org/")) + set_capability("vout display", 60) + add_shortcut("directfb") + set_callbacks(Open, Close) +vlc_module_end() /***************************************************************************** - * Module descriptor + * Local prototypes *****************************************************************************/ -vlc_module_begin () - set_shortname( "DirectFB" ) - set_category( CAT_VIDEO ) - set_subcategory( SUBCAT_VIDEO_VOUT ) - set_description( N_("DirectFB video output http://www.directfb.org/") ) - set_capability( "video output", 60 ) - add_shortcut( "directfb" ) - set_callbacks( Create, Destroy ) -vlc_module_end () - - -static int Create( vlc_object_t *p_this ) +static picture_pool_t *Pool (vout_display_t *, unsigned); +static void Display(vout_display_t *, picture_t *); +static int Control(vout_display_t *, int, va_list); +static void Manage (vout_display_t *); + +/* */ +static int OpenDisplay (vout_display_t *); +static void CloseDisplay(vout_display_t *); + +/* */ +struct vout_display_sys_t { + /* */ + IDirectFB *directfb; + IDirectFBSurface *primary; + DFBSurfacePixelFormat pixel_format; + + /* */ + int width; + int height; + + /* */ + picture_pool_t *pool; +}; + +/* */ +static int Open(vlc_object_t *object) { - vout_thread_t *p_vout = (vout_thread_t *)p_this; - vout_sys_t *p_sys = NULL; - p_vout->pf_init = Init; - p_vout->pf_end = End; - p_vout->pf_manage = Manage; - p_vout->pf_render = NULL; - p_vout->pf_display = Display; + vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys; /* Allocate structure */ - p_vout->p_sys = p_sys = malloc( sizeof( vout_sys_t ) ); - if( !p_sys ) + vd->sys = sys = malloc(sizeof(*sys)); + if (!sys) return VLC_ENOMEM; - p_sys->p_directfb = NULL; - p_sys->p_primary = NULL; - p_sys->p_pixels = NULL; - p_sys->i_width = 0; - p_sys->i_height = 0; + sys->directfb = NULL; + sys->primary = NULL; + sys->width = 0; + sys->height = 0; + sys->pool = NULL; /* Init DirectFB */ - if( DirectFBInit(NULL,NULL) != DFB_OK ) - { - msg_Err(p_vout, "Cannot init DirectFB"); - free( p_sys ); + if (DirectFBInit(NULL,NULL) != DFB_OK) { + msg_Err(vd, "Cannot init DirectFB"); + free(sys); return VLC_EGENERIC; } - if( OpenDisplay( p_vout ) ) - { - msg_Err(p_vout, "Cannot create primary surface"); - free( p_sys ); + if (OpenDisplay(vd)) { + msg_Err(vd, "Cannot create primary surface"); + Close(VLC_OBJECT(vd)); + return VLC_EGENERIC; + } + vout_display_DeleteWindow(vd, NULL); + + /* */ + video_format_t fmt = vd->fmt; + + switch (sys->pixel_format) { + case DSPF_RGB332: + /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ + fmt.i_chroma = VLC_CODEC_RGB8; + fmt.i_rmask = 0x7 << 5; + fmt.i_gmask = 0x7 << 2; + fmt.i_bmask = 0x3 << 0; + break; + case DSPF_RGB16: + /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ + fmt.i_chroma = VLC_CODEC_RGB16; + fmt.i_rmask = 0x1f << 11; + fmt.i_gmask = 0x3f << 5; + fmt.i_bmask = 0x1f << 0; + break; + case DSPF_RGB24: + /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ + fmt.i_chroma = VLC_CODEC_RGB24; + fmt.i_rmask = 0xff << 16; + fmt.i_gmask = 0xff << 8; + fmt.i_bmask = 0xff << 0; + break; + case DSPF_RGB32: + /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ + fmt.i_chroma = VLC_CODEC_RGB32; + fmt.i_rmask = 0xff << 16; + fmt.i_gmask = 0xff << 8; + fmt.i_bmask = 0xff << 0; + break; + default: + msg_Err(vd, "unknown screen depth %i", sys->pixel_format); + Close(VLC_OBJECT(vd)); return VLC_EGENERIC; } + + fmt.i_width = sys->width; + fmt.i_height = sys->height; + + /* */ + vout_display_info_t info = vd->info; + info.has_hide_mouse = true; + + /* */ + vd->fmt = fmt; + vd->info = info; + vd->pool = Pool; + vd->prepare = NULL; + vd->display = Display; + vd->control = Control; + vd->manage = Manage; + + /* */ + vout_display_SendEventFullscreen(vd, true); + vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true); return VLC_SUCCESS; } - -static int Init( vout_thread_t *p_vout ) +static void Close(vlc_object_t *object) { - vout_sys_t *p_sys = p_vout->p_sys; - IDirectFBSurface *p_primary = (IDirectFBSurface *) p_vout->p_sys->p_primary; - uint8_t* p_pixels = NULL; - picture_t *p_pic = NULL; - int i_rlength, i_glength, i_blength; - int i_roffset, i_goffset, i_boffset; - int i_line_pitch; - int i_size; - int i_index; - - I_OUTPUTPICTURES = 0; - - switch( p_sys->p_pixel_format ) - { - case DSPF_RGB332: - /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ - /* i_pixel_pitch = 1; */ - i_rlength = 3; - i_roffset = 5; - i_glength = 3; - i_goffset = 2; - i_blength = 2; - i_boffset = 0; - p_vout->output.i_chroma = VLC_CODEC_RGB8; - break; - - case DSPF_RGB16: - /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ - /* i_pixel_pitch = 2; */ - i_rlength = 5; - i_roffset = 11; - i_glength = 6; - i_goffset = 5; - i_blength = 5; - i_boffset = 0; - p_vout->output.i_chroma = VLC_CODEC_RGB16; - break; - - case DSPF_RGB24: - /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ - /* i_pixel_pitch = 3; */ - i_rlength = 8; - i_roffset = 16; - i_glength = 8; - i_goffset = 8; - i_blength = 8; - i_boffset = 0; - p_vout->output.i_chroma = VLC_CODEC_RGB24; - break; - - case DSPF_RGB32: - /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ - /* i_pixel_pitch = 4; */ - i_rlength = 8; - i_roffset = 16; - i_glength = 8; - i_goffset = 8; - i_blength = 8; - i_boffset = 0; - p_vout->output.i_chroma = VLC_CODEC_RGB32; - break; - - default: - msg_Err( p_vout, "unknown screen depth %i", - p_sys->p_pixel_format ); - return VLC_EGENERIC; - } - /* Set the RGB masks */ - p_vout->output.i_rmask = ( (1 << i_rlength) - 1 ) << i_roffset; - p_vout->output.i_gmask = ( (1 << i_glength) - 1 ) << i_goffset; - p_vout->output.i_bmask = ( (1 << i_blength) - 1 ) << i_boffset; - - /* Width and height */ - p_vout->output.i_width = p_sys->i_width; - p_vout->output.i_height = p_sys->i_height; - - /* The aspect */ - p_vout->output.i_aspect = (p_sys->i_width * VOUT_ASPECT_FACTOR) / - p_sys->i_height; - - /* Try to initialize 1 buffer */ - /* Find an empty picture slot */ - for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) - { - if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) - { - p_pic = p_vout->p_picture + i_index; - break; - } - } + vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys = vd->sys; - /* Allocate the picture */ - if( !p_pic ) - return VLC_EGENERIC; + if (sys->pool) + picture_pool_Delete(sys->pool); - /* get the pixels */ - if( p_primary->Lock( p_primary, DSLF_READ, (void **) &p_pixels, - &i_line_pitch) != DFB_OK ) - return VLC_EGENERIC; + CloseDisplay(vd); + free(sys); +} - /* allocate p_pixels */ - i_size = i_line_pitch * p_sys->i_height; - p_sys->p_pixels = malloc( i_size ); - if( p_sys->p_pixels == NULL ) - { - p_primary->Unlock(p_primary); - return VLC_ENOMEM; - } +/* */ +static picture_pool_t *Pool(vout_display_t *vd, unsigned count) +{ + vout_display_sys_t *sys = vd->sys; - /* copy pixels */ - memcpy( p_sys->p_pixels, p_pixels, i_size ); - if( p_primary->Unlock(p_primary) != DFB_OK ) - { - return VLC_EGENERIC; - } + if (!sys->pool) + sys->pool = picture_pool_NewFromFormat(&vd->fmt, count); + return sys->pool; +} - p_pic->p->p_pixels = p_sys->p_pixels; - p_pic->p->i_pixel_pitch = i_line_pitch / p_sys->i_width; - p_pic->p->i_lines = p_sys->i_height; - p_pic->p->i_visible_lines = p_sys->i_height; - p_pic->p->i_pitch = i_line_pitch; - p_pic->p->i_visible_pitch = i_line_pitch; - p_pic->i_planes = 1; - p_pic->i_status = DESTROYED_PICTURE; - p_pic->i_type = DIRECT_PICTURE; +static void Display(vout_display_t *vd, picture_t *picture) +{ + vout_display_sys_t *sys = vd->sys; - PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; + IDirectFBSurface *primary = sys->primary; - I_OUTPUTPICTURES++; + void *pixels; + int pitch; + if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) == DFB_OK) { + picture_resource_t rsc; - return VLC_SUCCESS; -} + memset(&rsc, 0, sizeof(rsc)); + rsc.p[0].p_pixels = pixels; + rsc.p[0].i_lines = sys->height; + rsc.p[0].i_pitch = pitch; -static void End( vout_thread_t *p_vout ) -{ - vout_sys_t *p_sys = p_vout->p_sys; + picture_t *direct = picture_NewFromResource(&vd->fmt, &rsc); + if (direct) { + picture_Copy(direct, picture); + picture_Release(direct); + } - free( p_sys->p_pixels ); + if (primary->Unlock(primary) == DFB_OK) + primary->Flip(primary, NULL, 0); + } + picture_Release(picture); } -static void Destroy( vlc_object_t *p_this ) +static int Control(vout_display_t *vd, int query, va_list args) { - vout_thread_t *p_vout = (vout_thread_t *)p_this; - vout_sys_t *p_sys = p_vout->p_sys; - - CloseDisplay( p_vout ); - free( p_sys ); - p_sys = NULL; + switch (query) { + case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: { + const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *); + if (cfg->display.width != vd->fmt.i_width || + cfg->display.height != vd->fmt.i_height) + return VLC_EGENERIC; + return VLC_SUCCESS; + } + default: + msg_Err(vd, "Unsupported query in vout display directfb"); + return VLC_EGENERIC; + } } -static int Manage( vout_thread_t *p_vout ) +static void Manage (vout_display_t *vd) { - return VLC_SUCCESS; + VLC_UNUSED(vd); } -static void Display( vout_thread_t *p_vout, picture_t *p_pic ) +static int OpenDisplay(vout_display_t *vd) { - vout_sys_t *p_sys = p_vout->p_sys; - IDirectFBSurface *p_primary = (IDirectFBSurface *) p_sys->p_primary; - uint8_t* p_pixels = NULL; - int i_size; - int i_line_pitch; - - /* get the pixels */ - if( p_primary->Lock( p_primary, DSLF_WRITE, - (void **) &p_pixels, - &i_line_pitch) == DFB_OK ) - { - i_size = i_line_pitch * p_vout->p_sys->i_height; - - /* copy pixels */ - memcpy( p_pixels, p_pic->p->p_pixels, i_size); - if( p_primary->Unlock(p_primary) == DFB_OK ) - { - p_primary->Flip(p_primary, NULL, 0); - } - } -} + vout_display_sys_t *sys = vd->sys; -static int OpenDisplay( vout_thread_t *p_vout ) -{ - vout_sys_t *p_sys = p_vout->p_sys; - IDirectFB *p_directfb = NULL; - IDirectFBSurface *p_primary = NULL; DFBSurfaceDescription dsc; - /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/ dsc.flags = DSDESC_CAPS; dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING; - /*dsc.width = 352;*/ /*dsc.height = 240;*/ - if( DirectFBCreate( &p_directfb ) != DFB_OK ) - return VLC_EGENERIC; - p_sys->p_directfb = p_directfb; - if( !p_directfb ) + IDirectFB *directfb = NULL; + if (DirectFBCreate(&directfb) != DFB_OK || !directfb) return VLC_EGENERIC; + sys->directfb = directfb; - if( p_directfb->CreateSurface( p_directfb, &dsc, &p_primary ) ) + IDirectFBSurface *primary = NULL; + if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary) return VLC_EGENERIC; + sys->primary = primary; - p_sys->p_primary = p_primary; - if( !p_primary ) - return VLC_EGENERIC; - - p_primary->GetSize( p_primary, &p_sys->i_width, - &p_sys->i_height ); - p_primary->GetPixelFormat( p_primary, &p_sys->p_pixel_format ); - p_primary->FillRectangle( p_primary, 0, 0, p_sys->i_width, - p_sys->i_height ); - p_primary->Flip( p_primary, NULL, 0 ); + primary->GetSize(primary, &sys->width, &sys->height); + primary->GetPixelFormat(primary, &sys->pixel_format); + primary->FillRectangle(primary, 0, 0, sys->width, sys->height); + primary->Flip(primary, NULL, 0); return VLC_SUCCESS; } -static void CloseDisplay( vout_thread_t *p_vout ) +static void CloseDisplay(vout_display_t *vd) { - vout_sys_t *p_sys = p_vout->p_sys; - IDirectFB *p_directfb = p_sys->p_directfb; - IDirectFBSurface *p_primary = p_sys->p_primary; + vout_display_sys_t *sys = vd->sys; - if( p_primary ) - p_primary->Release( p_primary ); + IDirectFBSurface *primary = sys->primary; + if (primary) + primary->Release(primary); - if( p_directfb ) - p_directfb->Release( p_directfb ); + IDirectFB *directfb = sys->directfb; + if (directfb) + directfb->Release(directfb); } +