Changeset c28d3216e9fe9df4631f2c1f0306711c63a9823e

Show
Ignore:
Timestamp:
01/25/08 19:59:31 (7 months ago)
Author:
Jean-Paul Saman <jpsaman@videolan.org>
git-committer:
Jean-Paul Saman <jpsaman@videolan.org> 1201287571 +0000
git-parent:

[e5762306a3dc2ebc7487a4b96f3fca2a5dc522d1]

git-author:
Jean-Paul Saman <jpsaman@videolan.org> 1201287571 +0000
Message:

If the framebuffer hardware doesn't support double buffering in hardware, then do this in software. It will increase vout memory consumption by at least one output picture size, but will guarantee smooth subpictures in the video output.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/video_output/fb.c

    r99fab90 rc28d321  
    5858static int  Control   ( vout_thread_t *, int, va_list ); 
    5959 
     60static int  NewPicture     ( vout_thread_t *, picture_t * ); 
     61static void FreePicture    ( vout_thread_t *, picture_t * ); 
     62 
    6063static int  OpenDisplay    ( vout_thread_t * ); 
    6164static void CloseDisplay   ( vout_thread_t * ); 
     
    6467static void GfxMode        ( int i_tty ); 
    6568 
     69#define MAX_DIRECTBUFFERS 1 
     70 
    6671/***************************************************************************** 
    6772 * Module descriptor 
     
    9095    "Select the resolution for the framebuffer. Currently it supports " \ 
    9196    "the values 0=QCIF 1=CIF 2=NTSC 3=PAL, 4=auto (default 4=auto)" ) 
     97 
     98#define HW_ACCEL_TEXT N_("Framebuffer uses hw acceleration.") 
     99#define HW_ACCEL_LONGTEXT N_( \ 
     100    "If your framebuffer supports hardware acceleration or does double buffering " \ 
     101    "in hardware then you must disable this option. It then does double buffering " \ 
     102    "in software." ) 
    92103 
    93104vlc_module_begin(); 
     
    104115    add_integer( "fb-mode", 4, NULL, FB_MODE_TEXT, FB_MODE_LONGTEXT, 
    105116                 VLC_TRUE ); 
     117    add_bool( "fb-hw-accel", VLC_TRUE, NULL, HW_ACCEL_TEXT, HW_ACCEL_LONGTEXT, 
     118              VLC_TRUE ); 
    106119    set_description( _("GNU/Linux console framebuffer video output") ); 
    107120    set_capability( "video output", 30 ); 
     
    134147    struct fb_cmap              fb_cmap;                /* original colormap */ 
    135148    uint16_t                    *p_palette;              /* original palette */ 
     149    vlc_bool_t                  b_hw_accel;          /* has hardware support */ 
    136150 
    137151    /* Video information */ 
     
    146160    byte_t *    p_video;                                      /* base adress */ 
    147161    size_t      i_page_size;                                    /* page size */ 
     162}; 
     163 
     164struct picture_sys_t 
     165{ 
     166    byte_t *    p_data;                                       /* base adress */ 
    148167}; 
    149168 
     
    179198    p_vout->pf_display = Display; 
    180199    p_vout->pf_control = Control; 
     200 
     201    /* Does the framebuffer uses hw acceleration? */ 
     202    p_sys->b_hw_accel = p_sys->b_tty = var_CreateGetBool( p_vout, "fb-hw-accel" ); 
    181203 
    182204    /* Set tty and fb devices */ 
     
    355377} 
    356378 
     379 
     380/***************************************************************************** 
     381 * Destroy: destroy FB video thread output method 
     382 ***************************************************************************** 
     383 * Terminate an output method created by Create 
     384 *****************************************************************************/ 
     385static void Destroy( vlc_object_t *p_this ) 
     386{ 
     387    vout_thread_t *p_vout = (vout_thread_t *)p_this; 
     388 
     389    CloseDisplay( p_vout ); 
     390 
     391    if( p_vout->p_sys->b_tty ) 
     392    { 
     393        /* Reset the terminal */ 
     394        ioctl( p_vout->p_sys->i_tty, VT_SETMODE, &p_vout->p_sys->vt_mode ); 
     395 
     396        /* Remove signal handlers */ 
     397        sigaction( SIGUSR1, &p_vout->p_sys->sig_usr1, NULL ); 
     398        sigaction( SIGUSR2, &p_vout->p_sys->sig_usr2, NULL ); 
     399 
     400        /* Reset the keyboard state */ 
     401        tcsetattr( 0, 0, &p_vout->p_sys->old_termios ); 
     402 
     403        /* Return to text mode */ 
     404        TextMode( p_vout->p_sys->i_tty ); 
     405    } 
     406 
     407    /* Destroy structure */ 
     408    free( p_vout->p_sys ); 
     409} 
     410 
     411/***************************************************************************** 
     412 * NewPicture: allocate a picture 
     413 ***************************************************************************** 
     414 * Returns 0 on success, -1 otherwise 
     415 *****************************************************************************/ 
     416static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ) 
     417{ 
     418    /* We know the chroma, allocate a buffer which will be used 
     419     * directly by the decoder */ 
     420    p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); 
     421    if( p_pic->p_sys == NULL ) 
     422    { 
     423        return VLC_ENOMEM; 
     424    } 
     425 
     426    /* Fill in picture_t fields */ 
     427    vout_InitPicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma, 
     428                      p_vout->output.i_width, p_vout->output.i_height, 
     429                      p_vout->output.i_aspect ); 
     430 
     431    p_pic->p_sys->p_data = malloc( p_vout->p_sys->i_page_size ); 
     432    if( !p_pic->p_sys->p_data ) 
     433    { 
     434        free( p_pic->p_sys ); 
     435        p_pic->p_sys = NULL; 
     436        return VLC_ENOMEM; 
     437    } 
     438 
     439    p_pic->p->p_pixels = (uint8_t*) p_pic->p_sys->p_data; 
     440 
     441    p_pic->p->i_pixel_pitch = p_vout->p_sys->i_bytes_per_pixel; 
     442    p_pic->p->i_lines = p_vout->p_sys->var_info.yres; 
     443    p_pic->p->i_visible_lines = p_vout->p_sys->var_info.yres; 
     444 
     445    if( p_vout->p_sys->var_info.xres_virtual ) 
     446    { 
     447        p_pic->p->i_pitch = p_vout->p_sys->var_info.xres_virtual 
     448                             * p_vout->p_sys->i_bytes_per_pixel; 
     449    } 
     450    else 
     451    { 
     452        p_pic->p->i_pitch = p_vout->p_sys->var_info.xres 
     453                             * p_vout->p_sys->i_bytes_per_pixel; 
     454    } 
     455 
     456    p_pic->p->i_visible_pitch = p_vout->p_sys->var_info.xres 
     457                                 * p_vout->p_sys->i_bytes_per_pixel; 
     458    p_pic->i_planes = 1; 
     459 
     460    return VLC_SUCCESS; 
     461} 
     462 
     463/***************************************************************************** 
     464 * FreePicture: destroy a picture allocated with NewPicture 
     465 ***************************************************************************** 
     466 * Destroy Image AND associated data. 
     467 *****************************************************************************/ 
     468static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic ) 
     469{ 
     470    free( p_pic->p_sys->p_data ); 
     471    free( p_pic->p_sys ); 
     472    p_pic->p_sys = NULL; 
     473} 
     474 
    357475/***************************************************************************** 
    358476 * Init: initialize framebuffer video thread output method 
     
    362480    vout_sys_t *p_sys = p_vout->p_sys; 
    363481    int i_index; 
    364     picture_t *p_pic
     482    picture_t *p_pic = NULL
    365483 
    366484    I_OUTPUTPICTURES = 0; 
     
    426544    memset( p_sys->p_video, 0, p_sys->i_page_size ); 
    427545 
    428     /* Try to initialize 1 direct buffer */ 
    429     p_pic = NULL; 
    430  
    431     /* Find an empty picture slot */ 
    432     for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) 
    433     { 
    434         if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) 
    435         { 
    436             p_pic = p_vout->p_picture + i_index; 
    437             break; 
    438         } 
    439     } 
    440  
    441     /* Allocate the picture */ 
    442     if( p_pic == NULL ) 
    443     { 
    444         return VLC_EGENERIC; 
    445     } 
    446  
    447     /* We know the chroma, allocate a buffer which will be used 
    448      * directly by the decoder */ 
    449     p_pic->p->p_pixels = p_vout->p_sys->p_video; 
    450     p_pic->p->i_pixel_pitch = p_vout->p_sys->i_bytes_per_pixel; 
    451     p_pic->p->i_lines = p_vout->p_sys->var_info.yres
    452     p_pic->p->i_visible_lines = p_vout->p_sys->var_info.yres
    453  
    454     if( p_vout->p_sys->var_info.xres_virtual ) 
    455     { 
    456         p_pic->p->i_pitch = p_vout->p_sys->var_info.xres_virtual 
    457                              * p_vout->p_sys->i_bytes_per_pixel; 
     546    if( !p_sys->b_hw_accel ) 
     547    { 
     548        /* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */ 
     549        while( I_OUTPUTPICTURES < MAX_DIRECTBUFFERS ) 
     550        { 
     551            p_pic = NULL; 
     552 
     553            /* Find an empty picture slot */ 
     554            for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) 
     555            { 
     556            if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) 
     557                { 
     558                    p_pic = p_vout->p_picture + i_index; 
     559                    break; 
     560                } 
     561            } 
     562 
     563            /* Allocate the picture */ 
     564            if( p_pic == NULL || NewPicture( p_vout, p_pic ) ) 
     565            { 
     566                break; 
     567            } 
     568 
     569            p_pic->i_status = DESTROYED_PICTURE
     570            p_pic->i_type   = DIRECT_PICTURE
     571 
     572            PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; 
     573 
     574            I_OUTPUTPICTURES++; 
     575        } 
    458576    } 
    459577    else 
    460578    { 
    461         p_pic->p->i_pitch = p_vout->p_sys->var_info.xres 
    462                              * p_vout->p_sys->i_bytes_per_pixel; 
    463     } 
    464  
    465     p_pic->p->i_visible_pitch = p_vout->p_sys->var_info.xres 
    466                                  * p_vout->p_sys->i_bytes_per_pixel; 
    467     p_pic->i_planes = 1; 
    468     p_pic->i_status = DESTROYED_PICTURE; 
    469     p_pic->i_type   = DIRECT_PICTURE; 
    470  
    471     PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; 
    472  
    473     I_OUTPUTPICTURES++; 
     579        /* Try to initialize 1 direct buffer */ 
     580        p_pic = NULL; 
     581 
     582        /* Find an empty picture slot */ 
     583        for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) 
     584        { 
     585            if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) 
     586            { 
     587                p_pic = p_vout->p_picture + i_index; 
     588                break; 
     589            } 
     590        } 
     591 
     592        /* Allocate the picture */ 
     593        if( p_pic == NULL ) 
     594        { 
     595            return VLC_EGENERIC; 
     596        } 
     597 
     598        /* We know the chroma, allocate a buffer which will be used 
     599        * directly by the decoder */ 
     600        p_pic->p->p_pixels = p_vout->p_sys->p_video; 
     601        p_pic->p->i_pixel_pitch = p_vout->p_sys->i_bytes_per_pixel; 
     602        p_pic->p->i_lines = p_vout->p_sys->var_info.yres; 
     603        p_pic->p->i_visible_lines = p_vout->p_sys->var_info.yres; 
     604 
     605        if( p_vout->p_sys->var_info.xres_virtual ) 
     606        { 
     607            p_pic->p->i_pitch = p_vout->p_sys->var_info.xres_virtual 
     608                                * p_vout->p_sys->i_bytes_per_pixel; 
     609        } 
     610        else 
     611        { 
     612            p_pic->p->i_pitch = p_vout->p_sys->var_info.xres 
     613                                * p_vout->p_sys->i_bytes_per_pixel; 
     614        } 
     615 
     616        p_pic->p->i_visible_pitch = p_vout->p_sys->var_info.xres 
     617                                    * p_vout->p_sys->i_bytes_per_pixel; 
     618        p_pic->i_planes = 1; 
     619        p_pic->i_status = DESTROYED_PICTURE; 
     620        p_pic->i_type   = DIRECT_PICTURE; 
     621 
     622        PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; 
     623 
     624        I_OUTPUTPICTURES++; 
     625    } 
    474626 
    475627    return VLC_SUCCESS; 
     
    481633static void End( vout_thread_t *p_vout ) 
    482634{ 
     635    if( !p_vout->p_sys->b_hw_accel ) 
     636    { 
     637        int i_index; 
     638 
     639        /* Free the direct buffers we allocated */ 
     640        for( i_index = I_OUTPUTPICTURES ; i_index ; ) 
     641        { 
     642            i_index--; 
     643            FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] ); 
     644        } 
     645 
     646    } 
    483647    /* Clear the screen */ 
    484648    memset( p_vout->p_sys->p_video, 0, p_vout->p_sys->i_page_size ); 
    485 } 
    486  
    487 /***************************************************************************** 
    488  * Destroy: destroy FB video thread output method 
    489  ***************************************************************************** 
    490  * Terminate an output method created by Create 
    491  *****************************************************************************/ 
    492 static void Destroy( vlc_object_t *p_this ) 
    493 { 
    494     vout_thread_t *p_vout = (vout_thread_t *)p_this; 
    495  
    496     CloseDisplay( p_vout ); 
    497  
    498     if( p_vout->p_sys->b_tty ) 
    499     { 
    500         /* Reset the terminal */ 
    501         ioctl( p_vout->p_sys->i_tty, VT_SETMODE, &p_vout->p_sys->vt_mode ); 
    502  
    503         /* Remove signal handlers */ 
    504         sigaction( SIGUSR1, &p_vout->p_sys->sig_usr1, NULL ); 
    505         sigaction( SIGUSR2, &p_vout->p_sys->sig_usr2, NULL ); 
    506  
    507         /* Reset the keyboard state */ 
    508         tcsetattr( 0, 0, &p_vout->p_sys->old_termios ); 
    509  
    510         /* Return to text mode */ 
    511         TextMode( p_vout->p_sys->i_tty ); 
    512     } 
    513  
    514     /* Destroy structure */ 
    515     free( p_vout->p_sys ); 
    516649} 
    517650 
     
    609742            panned++; 
    610743        } 
     744    } 
     745 
     746    if( !p_vout->p_sys->b_hw_accel ) 
     747    { 
     748        p_vout->p_libvlc->pf_memcpy( p_vout->p_sys->p_video, p_pic->p->p_pixels, 
     749                                     p_vout->p_sys->i_page_size ); 
    611750    } 
    612751} 
     
    836975 * called by the VT driver, on terminal change. 
    837976 *****************************************************************************/ 
    838 static void SwitchDisplay(int i_signal
     977static void SwitchDisplay( int i_signal
    839978{ 
    840979#if 0