Changeset 350148d32c57a849a34dd44df89058b41f28531c

Show
Ignore:
Timestamp:
06/04/08 13:14:12 (3 months ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1212578052 +0200
git-parent:

[9675983e20ab9bd6d9784afbf01f72ade9f5a7db]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1212532083 +0200
Message:

Use filter chain in video output core.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_vout.h

    r2e2178f r350148d  
    3232 
    3333#include <vlc_es.h> 
     34#include <vlc_filter.h> 
    3435 
    3536/** Description of a planar graphic field */ 
     
    7980    int             i_status;                             /**< picture flags */ 
    8081    int             i_type;                /**< is picture a direct buffer ? */ 
    81     bool      b_slow;                 /**< is picture in slow memory ? */ 
     82    bool            b_slow;                 /**< is picture in slow memory ? */ 
    8283    int             i_matrix_coefficients;   /**< in YUV type, encoding type */ 
    8384    /**@}*/ 
     
    8990    unsigned        i_refcount;                  /**< link reference counter */ 
    9091    mtime_t         date;                                  /**< display date */ 
    91     bool      b_force; 
     92    bool            b_force; 
    9293    /**@}*/ 
    9394 
     
    9697     * @{ 
    9798     */ 
    98     bool      b_progressive;          /**< is it a progressive frame ? */ 
     99    bool            b_progressive;          /**< is it a progressive frame ? */ 
    99100    unsigned int    i_nb_fields;                  /**< # of displayed fields */ 
    100     bool      b_top_field_first;             /**< which field is first */ 
     101    bool            b_top_field_first;             /**< which field is first */ 
    101102    /**@}*/ 
    102103 
     
    140141    picture_t*      pp_picture[VOUT_MAX_PICTURES];             /**< pictures */ 
    141142    int             i_last_used_pic;              /**< last used pic in heap */ 
    142     bool      b_allow_modify_pics; 
     143    bool            b_allow_modify_pics; 
    143144 
    144145    /* Stuff used for truecolor RGB planes */ 
     
    249250    mtime_t         i_start;                  /**< beginning of display date */ 
    250251    mtime_t         i_stop;                         /**< end of display date */ 
    251     bool      b_ephemer;    /**< If this flag is set to true the subtitle 
     252    bool            b_ephemer;    /**< If this flag is set to true the subtitle 
    252253                                will be displayed untill the next one appear */ 
    253     bool      b_fade;                               /**< enable fading */ 
    254     bool      b_pausable;               /**< subpicture will be paused if 
     254    bool            b_fade;                               /**< enable fading */ 
     255    bool            b_pausable;               /**< subpicture will be paused if 
    255256                                                            stream is paused */ 
    256257    /**@}*/ 
     
    270271    int          i_original_picture_width;  /**< original width of the movie */ 
    271272    int          i_original_picture_height;/**< original height of the movie */ 
    272     bool   b_absolute;                       /**< position is absolute */ 
     273    bool         b_absolute;                       /**< position is absolute */ 
    273274    int          i_flags;                                /**< position flags */ 
    274275     /**@}*/ 
     
    366367 */ 
    367368 
    368 /** Maximum numbers of video filters2 that can be attached to a vout */ 
    369 #define MAX_VFILTERS 10 
    370  
    371369/** 
    372370 * Video output thread descriptor 
     
    394392                                                      \see \ref vout_changes */ 
    395393    float               f_gamma;                                  /**< gamma */ 
    396     bool          b_grayscale;         /**< color or grayscale display */ 
    397     bool          b_info;            /**< print additional information */ 
    398     bool          b_interface;                   /**< render interface */ 
    399     bool          b_scale;                  /**< allow picture scaling */ 
    400     bool          b_fullscreen;         /**< toogle fullscreen display */ 
     394    bool                b_grayscale;         /**< color or grayscale display */ 
     395    bool                b_info;            /**< print additional information */ 
     396    bool                b_interface;                   /**< render interface */ 
     397    bool                b_scale;                  /**< allow picture scaling */ 
     398    bool                b_fullscreen;         /**< toogle fullscreen display */ 
    401399    uint32_t            render_time;           /**< last picture render time */ 
    402400    unsigned int        i_window_width;              /**< video window width */ 
     
    437435    picture_heap_t      render;                       /**< rendered pictures */ 
    438436    picture_heap_t      output;                          /**< direct buffers */ 
    439     bool          b_direct;            /**< rendered are like direct ? */ 
    440     filter_t            *p_chroma;                      /**< translation tables */ 
     437    bool                b_direct;            /**< rendered are like direct ? */ 
     438    filter_t           *p_chroma;                    /**< translation tables */ 
    441439 
    442440    video_format_t      fmt_render;      /* render format (from the decoder) */ 
     
    449447 
    450448    /* Subpicture unit */ 
    451     spu_t            *p_spu; 
     449    spu_t          *p_spu; 
    452450 
    453451    /* Statistics */ 
    454     count_t          c_loops; 
    455     count_t          c_pictures, c_late_pictures; 
    456     mtime_t          display_jitter;    /**< average deviation from the PTS */ 
    457     count_t          c_jitter_samples;  /**< number of samples used 
     452    count_t         c_loops; 
     453    count_t         c_pictures, c_late_pictures; 
     454    mtime_t         display_jitter;    /**< average deviation from the PTS */ 
     455    count_t         c_jitter_samples;  /**< number of samples used 
    458456                                           for the calculation of the 
    459457                                           jitter  */ 
    460458    /** delay created by internal caching */ 
    461     int                 i_pts_delay; 
     459    int             i_pts_delay; 
    462460 
    463461    /* Filter chain */ 
    464     char *psz_filter_chain; 
    465     bool b_filter_change; 
    466  
    467     /* Video filter2 chain 
    468      * these are handled like in transcode.c 
    469      * XXX: we might need to merge the two chains (v1 and v2 filters) */ 
    470     char       *psz_vfilters[MAX_VFILTERS]; 
    471     config_chain_t *p_vfilters_cfg[MAX_VFILTERS]; 
    472     int         i_vfilters_cfg; 
    473  
    474     filter_t   *pp_vfilters[MAX_VFILTERS]; 
    475     int         i_vfilters; 
    476  
    477     bool b_vfilter_change; 
     462    char           *psz_filter_chain; 
     463    bool            b_filter_change; 
     464 
     465    /* Video filter2 chain */ 
     466    filter_chain_t *p_vf2_chain; 
     467    char           *psz_vf2; 
    478468 
    479469    /* Misc */ 
    480     bool       b_snapshot;     /**< take one snapshot on the next loop */ 
     470    bool            b_snapshot;     /**< take one snapshot on the next loop */ 
    481471 
    482472    /* Video output configuration */ 
     
    484474 
    485475    /* Show media title on videoutput */ 
    486     bool      b_title_show; 
     476    bool            b_title_show; 
    487477    mtime_t         i_title_timeout; 
    488478    int             i_title_position; 
  • src/video_output/video_output.c

    r218efb9 r350148d  
    8585int vout_Snapshot( vout_thread_t *, picture_t * ); 
    8686 
    87 /* Video filter2 parsing */ 
    88 static int ParseVideoFilter2Chain( vout_thread_t *, char * ); 
    89 static void RemoveVideoFilters2( vout_thread_t *p_vout ); 
    90  
    9187/* Display media title in OSD */ 
    9288static void DisplayTitleOnOSD( vout_thread_t *p_vout ); 
     
    9591 * Video Filter2 functions 
    9692 *****************************************************************************/ 
    97 struct filter_owner_sys_t 
    98 { 
    99     vout_thread_t *p_vout; 
    100 }; 
    101  
    10293static picture_t *video_new_buffer_filter( filter_t *p_filter ) 
    10394{ 
    10495    picture_t *p_picture; 
    105     vout_thread_t *p_vout = p_filter->p_owner->p_vout
     96    vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner
    10697 
    10798    p_picture = vout_CreatePicture( p_vout, 0, 0, 0 ); 
     
    112103static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic ) 
    113104{ 
    114     vout_DestroyPicture( p_filter->p_owner->p_vout, p_pic ); 
     105    vout_DestroyPicture( (vout_thread_t*)p_filter->p_owner, p_pic ); 
     106
     107 
     108static int video_filter_buffer_allocation_init( filter_t *p_filter, void *p_data ) 
     109
     110    p_filter->pf_vout_buffer_new = video_new_buffer_filter; 
     111    p_filter->pf_vout_buffer_del = video_del_buffer_filter; 
     112    p_filter->p_owner = p_data; /* p_vout */ 
     113    return VLC_SUCCESS; 
    115114} 
    116115 
     
    343342    { 
    344343        /* Look for the default filter configuration */ 
    345         var_Create( p_vout, "vout-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 
    346         var_Get( p_vout, "vout-filter", &val ); 
    347         p_vout->psz_filter_chain = val.psz_string; 
     344        p_vout->psz_filter_chain = 
     345            var_CreateGetStringCommand( p_vout, "vout-filter" ); 
    348346 
    349347        /* Apply video filter2 objects on the first vout */ 
    350         var_Create( p_vout, "video-filter", 
    351                     VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 
    352         var_Get( p_vout, "video-filter", &val ); 
    353         ParseVideoFilter2Chain( p_vout, val.psz_string ); 
    354         free( val.psz_string ); 
     348        p_vout->psz_vf2 = 
     349            var_CreateGetStringCommand( p_vout, "video-filter" ); 
    355350    } 
    356351    else 
     
    368363 
    369364        /* Create a video filter2 var ... but don't inherit values */ 
    370         var_Create( p_vout, "video-filter", VLC_VAR_STRING ); 
    371         ParseVideoFilter2Chain( p_vout, NULL ); 
     365        var_Create( p_vout, "video-filter", 
     366                    VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); 
     367        p_vout->psz_vf2 = var_GetString( p_vout, "video-filter" ); 
    372368    } 
    373369 
    374370    var_AddCallback( p_vout, "video-filter", VideoFilter2Callback, NULL ); 
    375     p_vout->b_vfilter_change = true; 
    376     p_vout->i_vfilters = 0
     371    p_vout->p_vf2_chain = filter_chain_New( p_vout, "video filter2", 
     372        false, video_filter_buffer_allocation_init, NULL, p_vout )
    377373 
    378374    /* Choose the video output module */ 
     
    957953 
    958954        /* Video Filter2 stuff */ 
    959         if( p_vout->b_vfilter_change == true ) 
    960         { 
    961             int i; 
     955        if( p_vout->psz_vf2 ) 
     956        { 
     957            es_format_t fmt; 
     958 
    962959            vlc_mutex_lock( &p_vout->vfilter_lock ); 
    963             RemoveVideoFilters2( p_vout ); 
    964             for( i = 0; i < p_vout->i_vfilters_cfg; i++ ) 
    965             { 
    966                 filter_t *p_vfilter = 
    967                     p_vout->pp_vfilters[p_vout->i_vfilters] = 
    968                         vlc_object_create( p_vout, VLC_OBJECT_FILTER ); 
    969  
    970                 vlc_object_attach( p_vfilter, p_vout ); 
    971  
    972                 p_vfilter->pf_vout_buffer_new = video_new_buffer_filter; 
    973                 p_vfilter->pf_vout_buffer_del = video_del_buffer_filter; 
    974  
    975                 if( !p_vout->i_vfilters ) 
    976                 { 
    977                     p_vfilter->fmt_in.video = p_vout->fmt_render; 
    978                 } 
    979                 else 
    980                 { 
    981                     p_vfilter->fmt_in.video = (p_vfilter-1)->fmt_out.video; 
    982                 } 
    983                 /* TODO: one day filters in the middle of the chain might 
    984                  * have a different fmt_out.video than fmt_render ... */ 
    985                 p_vfilter->fmt_out.video = p_vout->fmt_render; 
    986  
    987                 p_vfilter->p_cfg = p_vout->p_vfilters_cfg[i]; 
    988                 p_vfilter->p_module = module_Need( p_vfilter, "video filter2", 
    989                                                    p_vout->psz_vfilters[i], 
    990                                                    true ); 
    991  
    992                 if( p_vfilter->p_module ) 
    993                 { 
    994                     p_vfilter->p_owner = 
    995                         malloc( sizeof( filter_owner_sys_t ) ); 
    996                     p_vfilter->p_owner->p_vout = p_vout; 
    997                     p_vout->i_vfilters++; 
    998                     msg_Dbg( p_vout, "video filter found (%s)", 
    999                              p_vout->psz_vfilters[i] ); 
    1000                 } 
    1001                 else 
    1002                 { 
    1003                     msg_Err( p_vout, "no video filter found (%s)", 
    1004                              p_vout->psz_vfilters[i] ); 
    1005                     vlc_object_detach( p_vfilter ); 
    1006                     vlc_object_release( p_vfilter ); 
    1007                 } 
    1008             } 
    1009             p_vout->b_vfilter_change = false; 
     960 
     961            es_format_Init( &fmt, VIDEO_ES, p_vout->fmt_render.i_chroma ); 
     962            fmt.video = p_vout->fmt_render; 
     963            filter_chain_Reset( p_vout->p_vf2_chain, &fmt, &fmt ); 
     964 
     965            if( filter_chain_AppendFromString( p_vout->p_vf2_chain, 
     966                                               p_vout->psz_vf2 ) < 0 ) 
     967                msg_Err( p_vout, "Video filter chain creation failed" ); 
     968 
     969            else 
     970            { 
     971                free( p_vout->psz_vf2 ); 
     972                p_vout->psz_vf2 = NULL; 
     973            } 
    1010974            vlc_mutex_unlock( &p_vout->vfilter_lock ); 
    1011975        } 
     
    1013977        if( p_picture ) 
    1014978        { 
    1015             int i; 
    1016             for( i = 0; i < p_vout->i_vfilters; i++ ) 
    1017             { 
    1018                 picture_t *p_old = p_picture; 
    1019                 p_picture  = p_vout->pp_vfilters[i]->pf_video_filter( 
    1020                                  p_vout->pp_vfilters[i], p_picture ); 
    1021                 if( !p_picture ) 
    1022                 { 
    1023                     break; 
    1024                 } 
    1025                 /* FIXME: this is kind of wrong 
    1026                  * if you have 2 or more vfilters and the 2nd breaks, 
    1027                  * on the next loop the 1st one will be applied again */ 
    1028  
    1029                 /* if p_old and p_picture are the same (ie the filter 
    1030                  * worked on the old picture), then following code is 
    1031                  * still alright since i_status gets changed back to 
    1032                  * the right value */ 
    1033                 if( p_old->i_refcount ) 
    1034                 { 
    1035                     p_old->i_status = DISPLAYED_PICTURE; 
    1036                 } 
    1037                 else 
    1038                 { 
    1039                     p_old->i_status = DESTROYED_PICTURE; 
    1040                 } 
    1041                 p_picture->i_status = READY_PICTURE; 
    1042             } 
     979            p_picture = filter_chain_VideoFilter( p_vout->p_vf2_chain, 
     980                                                  p_picture ); 
    1043981        } 
    1044982 
     
    12941232 
    12951233    /* Destroy the video filters2 */ 
    1296     RemoveVideoFilters2( p_vout ); 
     1234    filter_chain_Delete( p_vout->p_vf2_chain ); 
    12971235 
    12981236    /* Destroy translation tables */ 
     
    15511489 * Video Filter2 stuff 
    15521490 *****************************************************************************/ 
    1553 static int ParseVideoFilter2Chain( vout_thread_t *p_vout, char *psz_vfilters ) 
    1554 { 
    1555     int i; 
    1556     for( i = 0; i < p_vout->i_vfilters_cfg; i++ ) 
    1557     { 
    1558         struct config_chain_t *p_cfg = 
    1559             p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg]; 
    1560         config_ChainDestroy( p_cfg ); 
    1561         free( p_vout->psz_vfilters[p_vout->i_vfilters_cfg] ); 
    1562         p_vout->psz_vfilters[p_vout->i_vfilters_cfg] = NULL; 
    1563     } 
    1564     p_vout->i_vfilters_cfg = 0; 
    1565     if( psz_vfilters && *psz_vfilters ) 
    1566     { 
    1567         char *psz_parser = psz_vfilters; 
    1568  
    1569         while( psz_parser && *psz_parser ) 
    1570         { 
    1571             psz_parser = config_ChainCreate( 
    1572                             &p_vout->psz_vfilters[p_vout->i_vfilters_cfg], 
    1573                             &p_vout->p_vfilters_cfg[p_vout->i_vfilters_cfg], 
    1574                             psz_parser ); 
    1575             msg_Dbg( p_vout, "adding vfilter: %s", 
    1576                      p_vout->psz_vfilters[p_vout->i_vfilters_cfg] ); 
    1577             p_vout->i_vfilters_cfg++; 
    1578             if( psz_parser && *psz_parser ) 
    1579             { 
    1580                 if( p_vout->i_vfilters_cfg == MAX_VFILTERS ) 
    1581                 { 
    1582                     msg_Warn( p_vout, 
    1583                   "maximum number of video filters reached. \"%s\" discarded", 
    1584                               psz_parser ); 
    1585                     break; 
    1586                 } 
    1587             } 
    1588         } 
    1589     } 
    1590     return VLC_SUCCESS; 
    1591 } 
    1592  
    15931491static int VideoFilter2Callback( vlc_object_t *p_this, char const *psz_cmd, 
    15941492                       vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
     
    15981496 
    15991497    vlc_mutex_lock( &p_vout->vfilter_lock ); 
    1600     ParseVideoFilter2Chain( p_vout, newval.psz_string ); 
    1601     p_vout->b_vfilter_change = true; 
     1498    p_vout->psz_vf2 = strdup( newval.psz_string ); 
    16021499    vlc_mutex_unlock( &p_vout->vfilter_lock ); 
    16031500 
    16041501    return VLC_SUCCESS; 
    1605 } 
    1606  
    1607 static void RemoveVideoFilters2( vout_thread_t *p_vout ) 
    1608 { 
    1609     int i; 
    1610     for( i = 0; i < p_vout->i_vfilters; i++ ) 
    1611     { 
    1612         vlc_object_detach( p_vout->pp_vfilters[i] ); 
    1613         if( p_vout->pp_vfilters[i]->p_module ) 
    1614         { 
    1615             module_Unneed( p_vout->pp_vfilters[i], 
    1616                            p_vout->pp_vfilters[i]->p_module ); 
    1617         } 
    1618  
    1619         free( p_vout->pp_vfilters[i]->p_owner ); 
    1620         vlc_object_release( p_vout->pp_vfilters[i] ); 
    1621     } 
    1622     p_vout->i_vfilters = 0; 
    16231502} 
    16241503