Changeset ae0b191df59c3f49e58d0bb3e9b3b020920f31b6

Show
Ignore:
Timestamp:
14/07/06 23:32:43 (2 years ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1152912763 +0000
git-parent:

[d9474d275af974e3f3d52bb020d24fe8664edd03]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1152912763 +0000
Message:

Adjust is now a "video filter2"

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/video_filter/adjust.c

    r778a77d rae0b191  
    22 * adjust.c : Contrast/Hue/Saturation/Brightness video plugin for vlc 
    33 ***************************************************************************** 
    4  * Copyright (C) 2000, 2001, 2002, 2003 the VideoLAN team 
     4 * Copyright (C) 2000-2006 the VideoLAN team 
    55 * $Id$ 
    66 * 
    77 * Authors: Simon Latapie <garf@via.ecp.fr> 
     8 *          Antoine Cellerier <dionoea -at- videolan d0t org> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    3132 
    3233#include <vlc/vlc.h> 
    33 #include <vlc/vout.h> 
    34  
    35 #include "filter_common.h" 
     34#include <vlc/sout.h> 
     35#include <vlc/decoder.h> 
     36 
     37#include "vlc_filter.h" 
    3638 
    3739#ifndef M_PI 
     
    4749static void Destroy   ( vlc_object_t * ); 
    4850 
    49 static int  Init      ( vout_thread_t * ); 
    50 static void End       ( vout_thread_t * ); 
    51 static void Render    ( vout_thread_t *, picture_t * ); 
    52  
    53 static int  SendEvents( vlc_object_t *, char const *, 
    54                         vlc_value_t, vlc_value_t, void * ); 
     51static picture_t *Filter( filter_t *, picture_t * ); 
    5552 
    5653/***************************************************************************** 
     
    7370#define GAMMA_LONGTEXT N_("Set the image gamma, between 0.01 and 10. Defaults to 1.") 
    7471 
    75  
    7672vlc_module_begin(); 
    7773    set_description( _("Image properties filter") ); 
    7874    set_shortname( N_("Image adjust" )); 
    7975    set_category( CAT_VIDEO ); 
    80     set_subcategory( SUBCAT_VIDEO_VFILTER ); 
    81     set_capability( "video filter", 0 ); 
     76    set_subcategory( SUBCAT_VIDEO_VFILTER2 ); 
     77    set_capability( "video filter2", 0 ); 
    8278 
    8379    add_float_with_range( "contrast", 1.0, 0.0, 2.0, NULL, 
     
    9995vlc_module_end(); 
    10096 
    101 /***************************************************************************** 
    102  * vout_sys_t: adjust video output method descriptor 
    103  ***************************************************************************** 
    104  * This structure is part of the video output thread descriptor. 
    105  * It describes the adjust specific properties of an output thread. 
    106  *****************************************************************************/ 
    107 struct vout_sys_t 
     97static const char *ppsz_filter_options[] = { 
     98    "contrast", "brightness", "hue", "saturation", "gamma", 
     99    "brightness-threshold", NULL 
     100}; 
     101 
     102/***************************************************************************** 
     103 * filter_sys_t: adjust filter method descriptor 
     104 *****************************************************************************/ 
     105struct filter_sys_t 
    108106{ 
    109     vout_thread_t *p_vout; 
    110107}; 
    111108 
     
    116113 
    117114/***************************************************************************** 
    118  * Control: control facility for the vout (forwards to child vout) 
    119  *****************************************************************************/ 
    120 static int Control( vout_thread_t *p_vout, int i_query, va_list args ) 
    121 { 
    122     return vout_vaControl( p_vout->p_sys->p_vout, i_query, args ); 
    123 } 
    124  
    125 /***************************************************************************** 
    126115 * Create: allocates adjust video thread output method 
    127116 ***************************************************************************** 
     
    130119static int Create( vlc_object_t *p_this ) 
    131120{ 
    132     vout_thread_t *p_vout = (vout_thread_t *)p_this; 
     121    filter_t *p_filter = (filter_t *)p_this; 
     122 
     123    /* XXX: we might need to add/remove some FOURCCs ... */ 
     124    if(   p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','2','0') 
     125       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','Y','U','V') 
     126       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','2','0') 
     127       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','1','2') 
     128       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','U','Y','V') 
     129       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('U','Y','V','Y') 
     130       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('U','Y','N','V') 
     131       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','4','2','2') 
     132       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('c','y','u','v') 
     133       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','Y','2') 
     134       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','N','V') 
     135       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','Y','U') 
     136       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','1','1') 
     137       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','1','0') 
     138       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','V','U','9') 
     139       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','M','G','A') 
     140       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','2','2') 
     141       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','2','2') 
     142       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('I','4','4','4') 
     143       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('J','4','4','4') 
     144       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','P') 
     145       && p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','A') ) 
     146    { 
     147        msg_Err( p_filter, "Unsupported input chroma (%4s)", 
     148                 (char*)&(p_filter->fmt_in.video.i_chroma) ); 
     149        return VLC_EGENERIC; 
     150    } 
     151 
     152    if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ) 
     153    { 
     154        msg_Err( p_filter, "Input and output chromas don't match" ); 
     155        return VLC_EGENERIC; 
     156    } 
    133157 
    134158    /* Allocate structure */ 
    135     p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); 
    136     if( p_vout->p_sys == NULL ) 
    137     { 
    138         msg_Err( p_vout, "out of memory" ); 
     159    p_filter->p_sys = malloc( sizeof( filter_sys_t ) ); 
     160    if( p_filter->p_sys == NULL ) 
     161    { 
     162        msg_Err( p_filter, "out of memory" ); 
    139163        return VLC_ENOMEM; 
    140164    } 
    141165 
    142     p_vout->pf_init = Init; 
    143     p_vout->pf_end = End; 
    144     p_vout->pf_manage = NULL; 
    145     p_vout->pf_render = Render; 
    146     p_vout->pf_display = NULL; 
    147     p_vout->pf_control = Control; 
    148  
    149     var_Create( p_vout, "contrast", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
    150     var_Create( p_vout, "brightness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
    151     var_Create( p_vout, "hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
    152     var_Create( p_vout, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
    153     var_Create( p_vout, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
    154     var_Create( p_vout, "brightness-threshold", 
     166    p_filter->pf_video_filter = Filter; 
     167 
     168    /* needed to get options passed in transcode using the 
     169     * adjust{name=value} syntax */ 
     170    sout_CfgParse( p_filter, "", ppsz_filter_options, 
     171                   p_filter->p_cfg ); 
     172 
     173    var_Create( p_filter, "contrast", 
     174                VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
     175    var_Create( p_filter, "brightness", 
     176                VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
     177    var_Create( p_filter, "hue", 
     178                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
     179    var_Create( p_filter, "saturation", 
     180                VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
     181    var_Create( p_filter, "gamma", 
     182                VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
     183    var_Create( p_filter, "brightness-threshold", 
    155184                VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); 
    156185 
    157186    return VLC_SUCCESS; 
    158 } 
    159  
    160 /***************************************************************************** 
    161  * Init: initialize adjust video thread output method 
    162  *****************************************************************************/ 
    163 static int Init( vout_thread_t *p_vout ) 
    164 { 
    165     int i_index; 
    166     picture_t *p_pic; 
    167     video_format_t fmt = {0}; 
    168  
    169     I_OUTPUTPICTURES = 0; 
    170  
    171     /* Initialize the output structure */ 
    172     p_vout->output.i_chroma = p_vout->render.i_chroma; 
    173     p_vout->output.i_width  = p_vout->render.i_width; 
    174     p_vout->output.i_height = p_vout->render.i_height; 
    175     p_vout->output.i_aspect = p_vout->render.i_aspect; 
    176  
    177     fmt.i_width = fmt.i_visible_width = p_vout->render.i_width; 
    178     fmt.i_height = fmt.i_visible_height = p_vout->render.i_height; 
    179     fmt.i_x_offset = fmt.i_y_offset = 0; 
    180     fmt.i_chroma = p_vout->render.i_chroma; 
    181     fmt.i_aspect = p_vout->render.i_aspect; 
    182     fmt.i_sar_num = p_vout->render.i_aspect * fmt.i_height / fmt.i_width; 
    183     fmt.i_sar_den = VOUT_ASPECT_FACTOR; 
    184  
    185     /* Try to open the real video output */ 
    186     msg_Dbg( p_vout, "spawning the real video output" ); 
    187  
    188     p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt ); 
    189  
    190     /* Everything failed */ 
    191     if( p_vout->p_sys->p_vout == NULL ) 
    192     { 
    193         msg_Err( p_vout, "can't open vout, aborting" ); 
    194         return VLC_EGENERIC; 
    195     } 
    196  
    197     ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); 
    198  
    199     ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); 
    200  
    201     ADD_PARENT_CALLBACKS( SendEventsToChild ); 
    202  
    203     return VLC_SUCCESS; 
    204 } 
    205  
    206 /***************************************************************************** 
    207  * End: terminate adjust video thread output method 
    208  *****************************************************************************/ 
    209 static void End( vout_thread_t *p_vout ) 
    210 { 
    211     int i_index; 
    212  
    213     /* Free the fake output buffers we allocated */ 
    214     for( i_index = I_OUTPUTPICTURES ; i_index ; ) 
    215     { 
    216         i_index--; 
    217         free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); 
    218     } 
    219187} 
    220188 
     
    226194static void Destroy( vlc_object_t *p_this ) 
    227195{ 
    228     vout_thread_t *p_vout = (vout_thread_t *)p_this; 
    229  
    230     if( p_vout->p_sys->p_vout ) 
    231     { 
    232         DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); 
    233         vlc_object_detach( p_vout->p_sys->p_vout ); 
    234         vout_Destroy( p_vout->p_sys->p_vout ); 
    235     } 
    236  
    237     DEL_PARENT_CALLBACKS( SendEventsToChild ); 
    238  
    239     free( p_vout->p_sys ); 
     196    filter_t *p_filter = (filter_t *)p_this; 
     197    free( p_filter->p_sys ); 
    240198} 
    241199 
     
    247205 * next frame. 
    248206 *****************************************************************************/ 
    249 static void Render( vout_thread_t *p_vout, picture_t *p_pic ) 
     207static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ) 
    250208{ 
    251209    int pi_luma[256]; 
     
    264222    vlc_value_t val; 
    265223 
    266     /* This is a new frame. Get a structure from the video_output. */ 
    267     while( ( p_outpic = vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 ) ) 
    268               == NULL ) 
    269     { 
    270         if( p_vout->b_die || p_vout->b_error ) 
    271         { 
    272             return; 
    273         } 
    274         msleep( VOUT_OUTMEM_SLEEP ); 
    275     } 
    276  
    277     vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date ); 
    278     vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic ); 
     224    if( !p_pic ) return NULL; 
     225 
     226    p_outpic = p_filter->pf_vout_buffer_new( p_filter ); 
     227    if( !p_outpic ) 
     228    { 
     229        msg_Warn( p_filter, "can't get output picture" ); 
     230        if( p_pic->pf_release ) 
     231            p_pic->pf_release( p_pic ); 
     232        return NULL; 
     233    } 
    279234 
    280235    /* Getvariables */ 
    281     var_Get( p_vout, "contrast", &val ); 
     236    var_Get( p_filter, "contrast", &val ); 
    282237    i_cont = (int) ( val.f_float * 255 ); 
    283     var_Get( p_vout, "brightness", &val ); 
     238    var_Get( p_filter, "brightness", &val ); 
    284239    i_lum = (int) (( val.f_float - 1.0 ) * 255 ); 
    285     var_Get( p_vout, "hue", &val ); 
     240    var_Get( p_filter, "hue", &val ); 
    286241    f_hue = (float) ( val.i_int * M_PI / 180 ); 
    287     var_Get( p_vout, "saturation", &val ); 
     242    var_Get( p_filter, "saturation", &val ); 
    288243    i_sat = (int) (val.f_float * 256 ); 
    289     var_Get( p_vout, "gamma", &val ); 
     244    var_Get( p_filter, "gamma", &val ); 
    290245    f_gamma = 1.0 / val.f_float; 
    291     var_Get( p_vout, "brightness-threshold", &val ); 
     246    var_Get( p_filter, "brightness-threshold", &val ); 
    292247    b_thres = (vlc_bool_t) ( val.b_bool ); 
    293248 
     
    335290     */ 
    336291 
    337     p_in = p_pic->p[0].p_pixels; 
    338     p_in_end = p_in + p_pic->p[0].i_visible_lines * p_pic->p[0].i_pitch - 8; 
    339  
    340     p_out = p_outpic->p[0].p_pixels; 
     292    p_in = p_pic->p[Y_PLANE].p_pixels; 
     293    p_in_end = p_in + p_pic->p[Y_PLANE].i_visible_lines 
     294                      * p_pic->p[Y_PLANE].i_pitch - 8; 
     295 
     296    p_out = p_outpic->p[Y_PLANE].p_pixels; 
    341297 
    342298    for( ; p_in < p_in_end ; ) 
    343299    { 
    344         p_line_end = p_in + p_pic->p[0].i_visible_pitch - 8; 
     300        p_line_end = p_in + p_pic->p[Y_PLANE].i_visible_pitch - 8; 
    345301 
    346302        for( ; p_in < p_line_end ; ) 
     
    360316        } 
    361317 
    362         p_in += p_pic->p[0].i_pitch - p_pic->p[0].i_visible_pitch; 
    363         p_out += p_outpic->p[0].i_pitch - p_outpic->p[0].i_visible_pitch; 
     318        p_in += p_pic->p[Y_PLANE].i_pitch 
     319              - p_pic->p[Y_PLANE].i_visible_pitch; 
     320        p_out += p_outpic->p[Y_PLANE].i_pitch 
     321               - p_outpic->p[Y_PLANE].i_visible_pitch; 
    364322    } 
    365323 
     
    368326     */ 
    369327 
    370     p_in = p_pic->p[1].p_pixels; 
    371     p_in_v = p_pic->p[2].p_pixels; 
    372     p_in_end = p_in + p_pic->p[1].i_visible_lines * p_pic->p[1].i_pitch - 8; 
    373  
    374     p_out = p_outpic->p[1].p_pixels; 
    375     p_out_v = p_outpic->p[2].p_pixels; 
     328    p_in = p_pic->p[U_PLANE].p_pixels; 
     329    p_in_v = p_pic->p[V_PLANE].p_pixels; 
     330    p_in_end = p_in + p_pic->p[U_PLANE].i_visible_lines 
     331                      * p_pic->p[U_PLANE].i_pitch - 8; 
     332 
     333    p_out = p_outpic->p[U_PLANE].p_pixels; 
     334    p_out_v = p_outpic->p[V_PLANE].p_pixels; 
    376335 
    377336    i_sin = sin(f_hue) * 256; 
     
    394353        for( ; p_in < p_in_end ; ) 
    395354        { 
    396             p_line_end = p_in + p_pic->p[1].i_visible_pitch - 8; 
     355            p_line_end = p_in + p_pic->p[U_PLANE].i_visible_pitch - 8; 
    397356 
    398357            for( ; p_in < p_line_end ; ) 
     
    412371            } 
    413372 
    414             p_in += p_pic->p[1].i_pitch - p_pic->p[1].i_visible_pitch; 
    415             p_in_v += p_pic->p[2].i_pitch - p_pic->p[2].i_visible_pitch; 
    416             p_out += p_outpic->p[1].i_pitch - p_outpic->p[1].i_visible_pitch; 
    417             p_out_v += p_outpic->p[2].i_pitch - p_outpic->p[2].i_visible_pitch; 
     373            p_in += p_pic->p[U_PLANE].i_pitch 
     374                  - p_pic->p[U_PLANE].i_visible_pitch; 
     375            p_in_v += p_pic->p[V_PLANE].i_pitch 
     376                    - p_pic->p[V_PLANE].i_visible_pitch; 
     377            p_out += p_outpic->p[U_PLANE].i_pitch 
     378                   - p_outpic->p[U_PLANE].i_visible_pitch; 
     379            p_out_v += p_outpic->p[V_PLANE].i_pitch 
     380                     - p_outpic->p[V_PLANE].i_visible_pitch; 
    418381        } 
    419382    } 
     
    431394        for( ; p_in < p_in_end ; ) 
    432395        { 
    433             p_line_end = p_in + p_pic->p[1].i_visible_pitch - 8; 
     396            p_line_end = p_in + p_pic->p[U_PLANE].i_visible_pitch - 8; 
    434397 
    435398            for( ; p_in < p_line_end ; ) 
     
    447410            } 
    448411 
    449             p_in += p_pic->p[1].i_pitch - p_pic->p[1].i_visible_pitch; 
    450             p_in_v += p_pic->p[2].i_pitch - p_pic->p[2].i_visible_pitch; 
    451             p_out += p_outpic->p[1].i_pitch - p_outpic->p[1].i_visible_pitch; 
    452             p_out_v += p_outpic->p[2].i_pitch - p_outpic->p[2].i_visible_pitch; 
    453         } 
    454     } 
    455  
    456     vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic ); 
    457  
    458     vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); 
     412            p_in += p_pic->p[U_PLANE].i_pitch 
     413                  - p_pic->p[U_PLANE].i_visible_pitch; 
     414            p_in_v += p_pic->p[V_PLANE].i_pitch 
     415                    - p_pic->p[V_PLANE].i_visible_pitch; 
     416            p_out += p_outpic->p[U_PLANE].i_pitch 
     417                   - p_outpic->p[U_PLANE].i_visible_pitch; 
     418            p_out_v += p_outpic->p[V_PLANE].i_pitch 
     419                     - p_outpic->p[V_PLANE].i_visible_pitch; 
     420        } 
     421    } 
     422 
     423    p_outpic->date = p_pic->date; 
     424    p_outpic->b_force = p_pic->b_force; 
     425    p_outpic->i_nb_fields = p_pic->i_nb_fields; 
     426    p_outpic->b_progressive = p_pic->b_progressive; 
     427    p_outpic->b_top_field_first = p_pic->b_top_field_first; 
     428 
     429    p_pic->pf_release( p_pic ); 
     430 
     431    return p_outpic; 
    459432} 
    460  
    461 /***************************************************************************** 
    462  * SendEvents: forward mouse and keyboard events to the parent p_vout 
    463  *****************************************************************************/ 
    464 static int SendEvents( vlc_object_t *p_this, char const *psz_var, 
    465                        vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
    466 { 
    467     var_Set( (vlc_object_t *)p_data, psz_var, newval ); 
    468  
    469     return VLC_SUCCESS; 
    470 } 
    471  
    472 /***************************************************************************** 
    473  * SendEventsToChild: forward events to the child/children vout 
    474  *****************************************************************************/ 
    475 static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, 
    476                        vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
    477 { 
    478     vout_thread_t *p_vout = (vout_thread_t *)p_this; 
    479     var_Set( p_vout->p_sys->p_vout, psz_var, newval ); 
    480     return VLC_SUCCESS; 
    481 }