Converted directfb to "vout display" API.
authorLaurent Aimar <fenrir@videolan.org>
Mon, 31 Aug 2009 19:06:37 +0000 (21:06 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Mon, 31 Aug 2009 19:08:25 +0000 (21:08 +0200)
modules/video_output/directfb.c

index fd2ce25..47d62da 100644 (file)
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
-#include <vlc_vout.h>
+#include <vlc_vout_display.h>
+#include <vlc_picture_pool.h>
 
 #include <directfb.h>
 
 /*****************************************************************************
- * 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_t *Get    (vout_display_t *);
+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;
-    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;
     }
+
+    /* */
+    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->get     = Get;
+    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);
     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_t *Get(vout_display_t *vd)
+{
+    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, 1);
+        if (!sys->pool)
+            return NULL;
     }
+    return picture_pool_Get(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 );
+    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)
 {
-    VLC_UNUSED(p_vout);
-    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);
 }
+