Changeset ae42e9e71b81130e97ec3875cae5166907e9a062

Show
Ignore:
Timestamp:
07/03/05 20:28:52 (4 years ago)
Author:
Christophe Massiot <massiot@videolan.org>
git-committer:
Christophe Massiot <massiot@videolan.org> 1110223732 +0000
git-parent:

[60dca0985408e07119c7a55a011fb2d024fbb8d6]

git-author:
Christophe Massiot <massiot@videolan.org> 1110223732 +0000
Message:

* src/video_output/vout_subpictures.c: New function spu_MakeRegion which

reuses a given picture_t without allocating a new one.

* modules/video_output/picture.c: New --picture-height and width options

to do the scaling in the vout thread. Misc bug corrections.

* modules/video_filter/mosaic.c: Less overhead.
* modules/codec/ffmpeg/video_filter.c: Do the scaling before the conversion

in case the original size is bigger than the destination.

Files:

Legend:

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

    rd2a821e rae42e9e  
    11/***************************************************************************** 
    2  * vlc_codec.h: codec related structures 
     2 * vlc_filter.h: filter related structures 
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2003 VideoLAN 
  • include/vlc_spu.h

    raec298a rae42e9e  
    100100#define spu_CreateRegion(a,b) __spu_CreateRegion(VLC_OBJECT(a),b) 
    101101VLC_EXPORT( subpicture_region_t *,__spu_CreateRegion, ( vlc_object_t *, video_format_t * ) ); 
     102#define spu_MakeRegion(a,b,c) __spu_MakeRegion(VLC_OBJECT(a),b,c) 
     103VLC_EXPORT( subpicture_region_t *,__spu_MakeRegion, ( vlc_object_t *, video_format_t *, picture_t * ) ); 
    102104#define spu_DestroyRegion(a,b) __spu_DestroyRegion(VLC_OBJECT(a),b) 
    103105VLC_EXPORT( void, __spu_DestroyRegion, ( vlc_object_t *, subpicture_region_t * ) ); 
  • include/vlc_video.h

    r6b38501 rae42e9e  
    274274    subpicture_region_t * ( *pf_create_region ) ( vlc_object_t *, 
    275275                                                  video_format_t * ); 
     276    subpicture_region_t * ( *pf_make_region ) ( vlc_object_t *, 
     277                                                video_format_t *, picture_t * ); 
    276278    void ( *pf_destroy_region ) ( vlc_object_t *, subpicture_region_t * ); 
    277279 
  • modules/codec/ffmpeg/video_filter.c

    re00637c rae42e9e  
    114114    } 
    115115 
    116     avpicture_alloc( &p_sys->tmp_pic, p_sys->i_dst_ffmpeg_chroma, 
    117                      p_filter->fmt_in.video.i_width, 
    118                      p_filter->fmt_in.video.i_height ); 
     116    if( p_sys->b_resize && p_sys->b_convert ) 
     117    { 
     118        if ( p_filter->fmt_in.video.i_width * p_filter->fmt_in.video.i_height > 
     119             p_filter->fmt_out.video.i_width * p_filter->fmt_out.video.i_height ) 
     120        { 
     121            /* Resizing then conversion */ 
     122            avpicture_alloc( &p_sys->tmp_pic, p_sys->i_src_ffmpeg_chroma, 
     123                             p_filter->fmt_out.video.i_width, 
     124                             p_filter->fmt_out.video.i_height ); 
     125        } 
     126        else 
     127        { 
     128            /* Conversion then resizing */ 
     129            avpicture_alloc( &p_sys->tmp_pic, p_sys->i_dst_ffmpeg_chroma, 
     130                             p_filter->fmt_in.video.i_width, 
     131                             p_filter->fmt_in.video.i_height ); 
     132        } 
     133    } 
    119134 
    120135    msg_Dbg( p_filter, "input: %ix%i %4.4s -> %ix%i %4.4s", 
     
    192207    filter_sys_t *p_sys = p_filter->p_sys; 
    193208    AVPicture src_pic, dest_pic, inter_pic; 
     209    AVPicture *p_src, *p_dst; 
    194210    picture_t *p_pic_dst; 
    195211    vlc_bool_t b_resize = p_sys->b_resize; 
     
    239255            p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24; 
    240256 
    241 #if 0 
    242     if( p_sys->b_resize && 
    243         p_filter->fmt_in.video.i_width * p_filter->fmt_in.video.i_height > 
    244         p_filter->fmt_out.video.i_width * p_filter->fmt_out.video.i_height ) 
    245     { 
    246         img_resample( p_sys->p_rsc, &dest_pic, &p_sys->tmp_pic ); 
    247         b_resize = 0; 
    248     } 
    249 #endif 
     257    p_src = &src_pic; 
     258 
     259    if( b_resize && p_sys->p_rsc ) 
     260    { 
     261        p_dst = &dest_pic; 
     262        if ( p_filter->fmt_in.video.i_width * p_filter->fmt_in.video.i_height > 
     263             p_filter->fmt_out.video.i_width * p_filter->fmt_out.video.i_height ) 
     264        { 
     265            if ( p_sys->b_convert ) p_dst = &p_sys->tmp_pic; 
     266            img_resample( p_sys->p_rsc, p_dst, p_src ); 
     267            b_resize = VLC_FALSE; 
     268            p_src = p_dst; 
     269        } 
     270    } 
    250271 
    251272    if( p_sys->b_convert ) 
    252273    { 
    253         if( p_sys->b_resize ) inter_pic = p_sys->tmp_pic; 
    254         else inter_pic = dest_pic; 
    255  
    256         img_convert( &inter_pic, p_sys->i_dst_ffmpeg_chroma, 
    257                      &src_pic, p_sys->i_src_ffmpeg_chroma, 
    258                      p_filter->fmt_in.video.i_width, 
    259                      p_filter->fmt_in.video.i_height ); 
    260  
    261         src_pic = inter_pic; 
    262     } 
    263  
    264     if( p_sys->b_resize && p_sys->p_rsc ) 
    265     { 
    266         img_resample( p_sys->p_rsc, &dest_pic, &src_pic ); 
     274        video_format_t *p_fmt = &p_filter->fmt_out.video; 
     275        p_dst = &dest_pic; 
     276        if( b_resize ) 
     277        { 
     278            p_dst = &p_sys->tmp_pic; 
     279            p_fmt = &p_filter->fmt_in.video; 
     280        } 
     281 
     282        img_convert( p_dst, p_sys->i_dst_ffmpeg_chroma, 
     283                     p_src, p_sys->i_src_ffmpeg_chroma, 
     284                     p_fmt->i_width, p_fmt->i_height ); 
     285 
     286        p_src = p_dst; 
     287    } 
     288 
     289    if( b_resize && p_sys->p_rsc ) 
     290    { 
     291        p_dst = &dest_pic; 
     292        img_resample( p_sys->p_rsc, p_dst, p_src ); 
    267293    } 
    268294 
  • modules/video_filter/mosaic.c

    rba9826c rae42e9e  
    11/***************************************************************************** 
    2 * mosaic.c : Mosaic video plugin for vlc 
    3 ***************************************************************************** 
    4 * Copyright (C) 2004-2005 VideoLAN 
    5 * $Id$ 
    6 
    7 * Authors: Antoine Cellerier <dionoea@via.ecp.fr> 
    8 
    9 * This program is free software; you can redistribute it and/or modify 
    10 * it under the terms of the GNU General Public License as published by 
    11 * the Free Software Foundation; either version 2 of the License, or 
    12 * (at your option) any later version. 
    13 
    14 * This program is distributed in the hope that it will be useful, 
    15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    17 * GNU General Public License for more details. 
    18 
    19 * You should have received a copy of the GNU General Public License 
    20 * along with this program; if not, write to the Free Software 
    21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. 
     2 * mosaic.c : Mosaic video plugin for vlc 
     3 ***************************************************************************** 
     4 * Copyright (C) 2004-2005 VideoLAN 
     5 * $Id$ 
     6 * 
     7 * Authors: Antoine Cellerier <dionoea@via.ecp.fr> 
     8 *          Christophe Massiot <massiot@via.ecp.fr> 
     9 * 
     10 * This program is free software; you can redistribute it and/or modify 
     11 * it under the terms of the GNU General Public License as published by 
     12 * the Free Software Foundation; either version 2 of the License, or 
     13 * (at your option) any later version. 
     14 * 
     15 * This program is distributed in the hope that it will be useful, 
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     18 * GNU General Public License for more details. 
     19 * 
     20 * You should have received a copy of the GNU General Public License 
     21 * along with this program; if not, write to the Free Software 
     22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. 
    2223*****************************************************************************/ 
    2324 
    2425/***************************************************************************** 
    25 * Preamble 
    26 *****************************************************************************/ 
     26 * Preamble 
     27 *****************************************************************************/ 
    2728#include <stdlib.h>                                      /* malloc(), free() */ 
    2829#include <string.h> 
     
    3334 
    3435#include "vlc_filter.h" 
    35 #include "vlc_input.h" 
    36  
    3736#include "vlc_image.h" 
    3837 
    39 /***************************************************************************** 
    40 * Local prototypes 
    41 *****************************************************************************/ 
    42  
     38#include "../video_output/picture.h" 
     39 
     40/***************************************************************************** 
     41 * Local prototypes 
     42 *****************************************************************************/ 
    4343static int  CreateFilter    ( vlc_object_t * ); 
    4444static void DestroyFilter   ( vlc_object_t * ); 
     
    4747 
    4848static int MosaicCallback( vlc_object_t *, char const *, vlc_value_t, 
    49                             vlc_value_t, void * ); 
    50  
    51 /***************************************************************************** 
    52 * filter_sys_t : filter desriptor 
    53 *****************************************************************************/ 
    54  
    55 #include "../video_output/picture.h" 
    56  
     49                           vlc_value_t, void * ); 
     50 
     51/***************************************************************************** 
     52 * filter_sys_t : filter descriptor 
     53 *****************************************************************************/ 
    5754struct filter_sys_t 
    5855{ 
    59  
    6056    image_handler_t *p_image; 
     57#ifdef IMAGE_2PASSES 
    6158    image_handler_t *p_image2; 
     59#endif 
    6260    picture_t *p_pic; 
    6361 
    64     int i_pos; /* mosaic positioning method */ 
    65     int i_ar; /* do we keep aspect ratio ? */ 
     62    int i_position; /* mosaic positioning method */ 
     63    vlc_bool_t b_ar; /* do we keep the aspect ratio ? */ 
     64    vlc_bool_t b_keep; /* do we keep the original picture format ? */ 
    6665    int i_width, i_height; /* mosaic height and width */ 
    6766    int i_cols, i_rows; /* mosaic rows and cols */ 
     
    7372    int i_order_length; 
    7473 
     74    mtime_t i_delay; 
    7575}; 
    7676 
    7777/***************************************************************************** 
    78 * Module descriptor 
    79 *****************************************************************************/ 
    80  
    81 #define ALPHA_TEXT N_("Mosaic alpha blending (0 -> 255)") 
    82 #define ALPHA_LONGTEXT N_("Mosaic alpha blending (0 -> 255). default is 255") 
    83  
    84 #define HEIGHT_TEXT N_("Mosaic height in pixels") 
    85 #define WIDTH_TEXT N_("Mosaic width in pixels") 
    86 #define XOFFSET_TEXT N_("Mosaic top left corner x coordinate") 
    87 #define YOFFSET_TEXT N_("Mosaic top left corner y coordinate") 
    88 #define VBORDER_TEXT N_("Mosaic vertical border width in pixels") 
    89 #define HBORDER_TEXT N_("Mosaic horizontal border width in pixels") 
    90  
    91 #define POS_TEXT N_("Mosaic positioning method") 
    92 #define POS_LONGTEXT N_("Mosaic positioning method. auto : automatically chose the best number of rows and columns. fixed : used the user defined number of rows and columns.") 
    93 #define ROWS_TEXT N_("Mosaic number of rows") 
    94 #define COLS_TEXT N_("Mosaic number of columns") 
     78 * Module descriptor 
     79 *****************************************************************************/ 
     80#define ALPHA_TEXT N_("Alpha blending") 
     81#define ALPHA_LONGTEXT N_("Alpha blending (0 -> 255). Default is 255") 
     82 
     83#define HEIGHT_TEXT N_("Height in pixels") 
     84#define WIDTH_TEXT N_("Width in pixels") 
     85#define XOFFSET_TEXT N_("Top left corner x coordinate") 
     86#define YOFFSET_TEXT N_("Top left corner y coordinate") 
     87#define VBORDER_TEXT N_("Vertical border width in pixels") 
     88#define HBORDER_TEXT N_("Horizontal border width in pixels") 
     89 
     90#define POS_TEXT N_("Positioning method") 
     91#define POS_LONGTEXT N_("Positioning method. auto : automatically choose " \ 
     92        "the best number of rows and columns. fixed : use the user-defined " \ 
     93        "number of rows and columns.") 
     94#define ROWS_TEXT N_("Number of rows") 
     95#define COLS_TEXT N_("Number of columns") 
    9596#define AR_TEXT N_("Keep aspect ratio when resizing") 
     97#define KEEP_TEXT N_("Keep original size") 
    9698 
    9799#define ORDER_TEXT N_("Order as a comma separated list of picture-id(s)") 
     100 
     101#define DELAY_TEXT N_("Delay") 
     102#define DELAY_LONGTEXT N_("Pictures coming from the picture video outputs " \ 
     103        "will be delayed accordingly (in milliseconds, >= 100 ms). For high " \ 
     104        "values you will need to raise file-caching and others.") 
    98105 
    99106static int pi_pos_values[] = { 0, 1 }; 
     
    103110 
    104111vlc_module_begin(); 
    105     set_description( _("Mosaic video sub filter") ); 
     112    set_description( N_("Mosaic video sub filter") ); 
    106113    set_shortname( N_("Mosaic") ); 
    107114    set_capability( "sub filter", 0 ); 
     
    121128    add_integer( "mosaic-cols", 2, NULL, COLS_TEXT, COLS_TEXT, VLC_FALSE ); 
    122129    add_bool( "mosaic-keep-aspect-ratio", 0, NULL, AR_TEXT, AR_TEXT, VLC_FALSE ); 
     130    add_bool( "mosaic-keep-picture", 0, NULL, KEEP_TEXT, KEEP_TEXT, VLC_FALSE ); 
    123131    add_string( "mosaic-order", "", NULL, ORDER_TEXT, ORDER_TEXT, VLC_FALSE ); 
     132 
     133    add_integer( "mosaic-delay", 100, NULL, DELAY_TEXT, DELAY_LONGTEXT, 
     134                 VLC_FALSE ); 
    124135vlc_module_end(); 
    125136 
    126137 
    127138/***************************************************************************** 
    128 * CreateFiler: allocates mosaic video filter 
    129 *****************************************************************************/ 
    130  
     139 * CreateFiler: allocate mosaic video filter 
     140 *****************************************************************************/ 
    131141static int CreateFilter( vlc_object_t *p_this ) 
    132142{ 
    133143    filter_t *p_filter = (filter_t *)p_this; 
    134144    filter_sys_t *p_sys; 
     145    libvlc_t *p_libvlc = p_filter->p_libvlc; 
    135146    char *psz_order; 
    136147    int i_index; 
     
    143154        return VLC_ENOMEM; 
    144155    } 
    145     p_sys->p_image = image_HandlerCreate( p_filter ); 
    146     p_sys->p_image2 = image_HandlerCreate( p_filter ); 
    147156 
    148157    p_filter->pf_sub_filter = Filter; 
    149158    p_sys->p_pic = NULL; 
    150159 
    151     p_sys->i_width = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-width" ) ); 
    152     p_sys->i_height = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-height" ) ); 
    153  
    154     p_sys->i_xoffset = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-xoffset" ) ); 
    155     p_sys->i_yoffset = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-yoffset" ) ); 
    156  
    157     p_sys->i_vborder = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-vborder" ) ); 
    158     p_sys->i_hborder = __MAX( 0, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-hborder" ) ); 
    159  
    160     p_sys->i_rows = __MAX( 1, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-rows") ); 
    161     p_sys->i_cols = __MAX( 1, var_CreateGetInteger( p_filter->p_libvlc, "mosaic-cols") ); 
    162  
    163     p_sys->i_alpha = var_CreateGetInteger( p_filter->p_libvlc, "mosaic-alpha" ); 
    164     p_sys->i_alpha = __MIN( 255, __MAX( 0, p_sys->i_alpha ) ); 
    165  
    166     p_sys->i_pos = var_CreateGetInteger( p_filter->p_libvlc, "mosaic-position" ); 
    167     if( p_sys->i_pos > 1 || p_sys->i_pos < 0 ) p_sys->i_pos = 0; 
    168  
    169     p_sys->i_ar = var_CreateGetInteger( p_filter->p_libvlc, "mosaic-keep-aspect-ratio" ); 
     160#define GET_VAR( name, min, max )                                           \ 
     161    p_sys->i_##name = __MIN( max, __MAX( min,                               \ 
     162                var_CreateGetInteger( p_filter, "mosaic-" #name ) ) );      \ 
     163    var_Destroy( p_filter, "mosaic-" #name );                               \ 
     164    var_Create( p_libvlc, "mosaic-" #name, VLC_VAR_INTEGER );               \ 
     165    var_SetInteger( p_libvlc, "mosaic-" #name, p_sys->i_##name );           \ 
     166    var_AddCallback( p_libvlc, "mosaic-" #name, MosaicCallback, p_sys ); 
     167 
     168    GET_VAR( width, 0, INT32_MAX ); 
     169    GET_VAR( height, 0, INT32_MAX ); 
     170    GET_VAR( xoffset, 0, INT32_MAX ); 
     171    GET_VAR( yoffset, 0, INT32_MAX ); 
     172    GET_VAR( vborder, 0, INT32_MAX ); 
     173    GET_VAR( hborder, 0, INT32_MAX ); 
     174    GET_VAR( rows, 1, INT32_MAX ); 
     175    GET_VAR( cols, 1, INT32_MAX ); 
     176    GET_VAR( alpha, 0, 255 ); 
     177    GET_VAR( position, 0, 1 ); 
     178    GET_VAR( delay, 100, INT32_MAX ); 
     179    p_sys->i_delay *= 1000; 
     180 
     181    p_sys->b_ar = var_CreateGetBool( p_filter, "mosaic-keep-aspect-ratio" ); 
     182    var_Destroy( p_filter, "mosaic-keep-aspect-ratio" ); 
     183    var_Create( p_libvlc, "mosaic-keep-aspect-ratio", VLC_VAR_INTEGER ); 
     184    var_SetBool( p_libvlc, "mosaic-keep-aspect-ratio", p_sys->b_ar ); 
     185    var_AddCallback( p_libvlc, "mosaic-keep-aspect-ratio", MosaicCallback, 
     186                     p_sys ); 
     187 
     188    p_sys->b_keep = var_CreateGetBool( p_filter, "mosaic-keep-picture" ); 
     189    if ( !p_sys->b_keep ) 
     190    { 
     191        p_sys->p_image = image_HandlerCreate( p_filter ); 
     192#ifdef IMAGE_2PASSES 
     193        p_sys->p_image2 = image_HandlerCreate( p_filter ); 
     194#endif 
     195    } 
    170196 
    171197    p_sys->i_order_length = 0; 
    172198    p_sys->ppsz_order = NULL; 
    173     psz_order = var_CreateGetString( p_filter->p_libvlc, "mosaic-order" ); 
     199    psz_order = var_CreateGetString( p_filter, "mosaic-order" ); 
    174200 
    175201    if( psz_order[0] != 0 ) 
    176202    { 
    177         char* psz_end=NULL; 
     203        char *psz_end = NULL; 
    178204        i_index = 0; 
    179205        do 
     
    190216    } 
    191217 
    192     var_AddCallback( p_filter->p_libvlc, "mosaic-alpha", 
    193                      MosaicCallback, p_sys ); 
    194     var_AddCallback( p_filter->p_libvlc, "mosaic-height", 
    195                      MosaicCallback, p_sys ); 
    196     var_AddCallback( p_filter->p_libvlc, "mosaic-width", 
    197                      MosaicCallback, p_sys ); 
    198     var_AddCallback( p_filter->p_libvlc, "mosaic-xoffset", 
    199                      MosaicCallback, p_sys ); 
    200     var_AddCallback( p_filter->p_libvlc, "mosaic-yoffset", 
    201                      MosaicCallback, p_sys ); 
    202     var_AddCallback( p_filter->p_libvlc, "mosaic-vborder", 
    203                      MosaicCallback, p_sys ); 
    204     var_AddCallback( p_filter->p_libvlc, "mosaic-hborder", 
    205                      MosaicCallback, p_sys ); 
    206     var_AddCallback( p_filter->p_libvlc, "mosaic-position", 
    207                      MosaicCallback, p_sys ); 
    208     var_AddCallback( p_filter->p_libvlc, "mosaic-rows", 
    209                      MosaicCallback, p_sys ); 
    210     var_AddCallback( p_filter->p_libvlc, "mosaic-cols", 
    211                      MosaicCallback, p_sys ); 
    212     var_AddCallback( p_filter->p_libvlc, "mosaic-keep-aspect-ratio", 
    213                      MosaicCallback, p_sys ); 
     218    vlc_thread_set_priority( p_filter, VLC_THREAD_PRIORITY_OUTPUT ); 
    214219 
    215220    return VLC_SUCCESS; 
     
    217222 
    218223/***************************************************************************** 
    219 * DestroyFilter: destroy mosaic video filter 
    220 *****************************************************************************/ 
    221  
     224 * DestroyFilter: destroy mosaic video filter 
     225 *****************************************************************************/ 
    222226static void DestroyFilter( vlc_object_t *p_this ) 
    223227{ 
    224228    filter_t *p_filter = (filter_t*)p_this; 
    225229    filter_sys_t *p_sys = p_filter->p_sys; 
     230    libvlc_t *p_libvlc = p_filter->p_libvlc; 
    226231    int i_index; 
    227232 
    228     image_HandlerDelete( p_sys->p_image ); 
    229     image_HandlerDelete( p_sys->p_image2 ); 
     233    if( !p_sys->b_keep ) 
     234    { 
     235        image_HandlerDelete( p_sys->p_image ); 
     236#ifdef IMAGE_2PASSES 
     237        image_HandlerDelete( p_sys->p_image2 ); 
     238#endif 
     239    } 
    230240 
    231241    if( p_sys->i_order_length ) 
     
    238248    } 
    239249 
    240     var_Destroy( p_filter->p_libvlc, "mosaic-alpha" ); 
    241     var_Destroy( p_filter->p_libvlc, "mosaic-height" ); 
    242     var_Destroy( p_filter->p_libvlc, "mosaic-width" ); 
    243     var_Destroy( p_filter->p_libvlc, "mosaic-xoffset" ); 
    244     var_Destroy( p_filter->p_libvlc, "mosaic-yoffset" ); 
    245     var_Destroy( p_filter->p_libvlc, "mosaic-vborder" ); 
    246     var_Destroy( p_filter->p_libvlc, "mosaic-hborder" ); 
    247     var_Destroy( p_filter->p_libvlc, "mosaic-position" ); 
    248     var_Destroy( p_filter->p_libvlc, "mosaic-rows" ); 
    249     var_Destroy( p_filter->p_libvlc, "mosaic-cols" ); 
    250     var_Destroy( p_filter->p_libvlc, "mosaic-keep-aspect-ratio" ); 
     250    var_Destroy( p_libvlc, "mosaic-alpha" ); 
     251    var_Destroy( p_libvlc, "mosaic-height" ); 
     252    var_Destroy( p_libvlc, "mosaic-width" ); 
     253    var_Destroy( p_libvlc, "mosaic-xoffset" ); 
     254    var_Destroy( p_libvlc, "mosaic-yoffset" ); 
     255    var_Destroy( p_libvlc, "mosaic-vborder" ); 
     256    var_Destroy( p_libvlc, "mosaic-hborder" ); 
     257    var_Destroy( p_libvlc, "mosaic-position" ); 
     258    var_Destroy( p_libvlc, "mosaic-rows" ); 
     259    var_Destroy( p_libvlc, "mosaic-cols" ); 
     260    var_Destroy( p_libvlc, "mosaic-keep-aspect-ratio" ); 
     261 
    251262    if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic ); 
    252263    free( p_sys ); 
     
    254265 
    255266/***************************************************************************** 
    256 * Filter 
    257 *****************************************************************************/ 
    258  
     267 * MosaicReleasePicture : Hack to avoid picture duplication 
     268 *****************************************************************************/ 
     269static void MosaicReleasePicture( picture_t *p_picture ) 
     270
     271    picture_t *p_original_pic = (picture_t *)p_picture->p_sys; 
     272 
     273    p_original_pic->pf_release( p_original_pic ); 
     274
     275 
     276/***************************************************************************** 
     277 * Filter 
     278 *****************************************************************************/ 
    259279static subpicture_t *Filter( filter_t *p_filter, mtime_t date ) 
    260280{ 
    261  
    262281    filter_sys_t *p_sys = p_filter->p_sys; 
     282    libvlc_t *p_libvlc = p_filter->p_libvlc; 
     283 
    263284    subpicture_t *p_spu; 
    264285 
    265     libvlc_t *p_libvlc = p_filter->p_libvlc; 
    266     vlc_value_t val; 
    267286    int i_index, i_real_index, i_row, i_col; 
    268287    int i_greatest_real_index_used = p_sys->i_order_length - 1; 
     
    271290    subpicture_region_t *p_region_prev = NULL; 
    272291 
    273     struct picture_vout_t *p_picture_vout; 
     292    picture_vout_t *p_picture_vout; 
     293    vlc_value_t val, lockval; 
     294 
     295    /* Wait for the specified date. This is to avoid running too fast and 
     296     * take twice the same pictures. */ 
     297    mwait( date - p_sys->i_delay ); 
     298 
     299    if ( var_Get( p_libvlc, "picture-lock", &lockval ) ) 
     300        return NULL; 
     301 
     302    vlc_mutex_lock( lockval.p_address ); 
    274303 
    275304    if( var_Get( p_libvlc, "p_picture_vout", &val ) ) 
    276305    { 
     306        vlc_mutex_unlock( lockval.p_address ); 
    277307        return NULL; 
    278308    } 
     
    294324    p_spu->i_alpha = p_sys->i_alpha; 
    295325 
    296     vlc_mutex_lock( &p_picture_vout->lock ); 
    297  
    298     if( p_sys->i_pos == 0 ) /* use automatic positioning */ 
     326    if( p_sys->i_position == 0 ) /* use automatic positioning */ 
    299327    { 
    300328        int i_numpics = p_sys->i_order_length; /* keep slots and all */ 
    301         for( i_index = 0
    302              i_index < p_picture_vout->i_picture_num
    303              i_index ++ ) 
     329        for( i_index = 0
     330             i_index < p_picture_vout->i_picture_num
     331             i_index++ ) 
    304332        { 
    305333            if( p_picture_vout->p_pic[i_index].i_status 
    306                            == PICTURE_VOUT_E_OCCUPIED ) { 
     334                           == PICTURE_VOUT_E_OCCUPIED ) 
     335            { 
    307336                i_numpics ++; 
    308337                if( p_sys->i_order_length 
    309                     && p_picture_vout->p_pic[i_index].psz_id != 0 ){ 
    310                 /* we also want to leave slots for images given in mosaic-order 
    311                 that are not available in p_vout_picture */ 
     338                    && p_picture_vout->p_pic[i_index].psz_id != 0 ) 
     339                { 
     340                    /* We also want to leave slots for images given in 
     341                     * mosaic-order that are not available in p_vout_picture */ 
    312342                    int i; 
    313343                    for( i = 0; i < p_sys->i_order_length ; i++ ) 
    314344                    { 
    315                         if( ! strcmp( p_sys->ppsz_order[i], 
    316                                     p_picture_vout->p_pic[i_index].psz_id ) ) 
     345                        if( !strcmp( p_sys->ppsz_order[i], 
     346                                    p_picture_vout->p_pic[i_index].psz_id ) ) 
    317347                        { 
    318                             i_numpics --; 
     348                            i_numpics--; 
    319349                            break; 
    320350                        } 
     
    325355        } 
    326356        p_sys->i_rows = ((int)ceil(sqrt( (float)i_numpics ))); 
    327         p_sys->i_cols = ( i_numpics%p_sys->i_rows == 0 ? 
    328                             i_numpics/p_sys->i_rows : 
    329                             i_numpics/p_sys->i_rows + 1 ); 
     357        p_sys->i_cols = ( i_numpics % p_sys->i_rows == 0 ? 
     358                            i_numpics / p_sys->i_rows : 
     359                            i_numpics / p_sys->i_rows + 1 ); 
    330360    } 
    331361 
    332362    i_real_index = 0; 
    333363 
    334     for( i_index = 0 ; i_index < p_picture_vout->i_picture_num ; i_index ++ ) 
    335     { 
    336  
    337         video_format_t fmt_in = {0}, fmt_middle = {0}, fmt_out = {0}; 
    338  
    339         picture_t *p_converted, *p_middle; 
    340  
    341         if(  p_picture_vout->p_pic[i_index].p_picture == NULL ) 
    342         { 
    343             break; 
    344         } 
    345  
    346         if(  p_picture_vout->p_pic[i_index].i_status 
    347                == PICTURE_VOUT_E_AVAILABLE ) 
    348         { 
    349             msg_Dbg( p_filter, "Picture Vout Element is empty"); 
    350             break; 
    351         } 
     364    for( i_index = 0; i_index < p_picture_vout->i_picture_num; i_index++ ) 
     365    { 
     366        picture_vout_e_t *p_pic = &p_picture_vout->p_pic[i_index]; 
     367        video_format_t fmt_in = {0}, fmt_out = {0}; 
     368        picture_t *p_converted; 
     369#ifdef IMAGE_2PASSES 
     370        video_format_t fmt_middle = {0}; 
     371        picture_t *p_middle; 
     372#endif 
     373 
     374        if( p_pic->i_status == PICTURE_VOUT_E_AVAILABLE 
     375             || p_pic->p_picture == NULL ) 
     376        { 
     377            continue; 
     378        } 
     379 
    352380        if( p_sys->i_order_length == 0 ) 
    353             i_real_index ++; 
     381        { 
     382            i_real_index++; 
     383        } 
    354384        else 
    355385        { 
    356386            int i; 
    357             for( i =0; i <= p_sys->i_order_length; i++ ) 
     387            for( i = 0; i <= p_sys->i_order_length; i++ ) 
    358388            { 
    359389                if( i == p_sys->i_order_length ) break; 
    360                 if( strcmp( p_picture_vout->p_pic[i_index].psz_id, 
    361                     p_sys->ppsz_order[ i ] ) == 0 ) 
     390                if( strcmp( p_pic->psz_id, p_sys->ppsz_order[i] ) == 0 ) 
    362391                { 
    363392                    i_real_index = i; 
     
    368397                i_real_index = ++i_greatest_real_index_used; 
    369398        } 
    370         i_row = ( i_real_index / p_sys->i_cols ) % p_sys->i_rows
     399        i_row = ( i_real_index / p_sys->i_cols ) % p_sys->i_rows
    371400        i_col = i_real_index % p_sys->i_cols ; 
    372401 
    373         /* Convert the images */ 
    374 /*        fprintf (stderr, "Input image %ix%i %4.4s\n", 
    375                   p_picture_vout->p_pic[i_index].p_picture->format.i_width, 
    376                   p_picture_vout->p_pic[i_index].p_picture->format.i_height, 
    377                   (char *)&p_picture_vout->p_pic[i_index].p_picture->format.i_chroma );*/ 
    378  
    379         fmt_in.i_chroma = p_picture_vout->p_pic[i_index]. 
    380                                                 p_picture->format.i_chroma; 
    381         fmt_in.i_height = p_picture_vout->p_pic[i_index]. 
    382                                                 p_picture->format.i_height; 
    383         fmt_in.i_width = p_picture_vout->p_pic[i_index]. 
    384                                                 p_picture->format.i_width; 
    385  
    386  
    387         fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); 
    388         fmt_out.i_width = fmt_in.i_width * 
    389             ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) 
    390               / p_sys->i_cols ) / fmt_in.i_width; 
    391         fmt_out.i_height = fmt_in.i_height * 
    392             ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) 
    393               / p_sys->i_rows ) / fmt_in.i_height; 
    394         if( p_sys->i_ar ) /* keep aspect ratio */ 
    395         { 
    396             if( (float)fmt_out.i_width/(float)fmt_out.i_height 
    397                 > (float)fmt_in.i_width/(float)fmt_in.i_height ) 
     402        if( !p_sys->b_keep ) 
     403        { 
     404            /* Convert the images */ 
     405            fmt_in.i_chroma = p_pic->p_picture->format.i_chroma; 
     406            fmt_in.i_height = p_pic->p_picture->format.i_height; 
     407            fmt_in.i_width = p_pic->p_picture->format.i_width; 
     408 
     409            fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); 
     410            fmt_out.i_width = fmt_in.i_width * 
     411                ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) 
     412                  / p_sys->i_cols ) / fmt_in.i_width; 
     413            fmt_out.i_height = fmt_in.i_height * 
     414                ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) 
     415                  / p_sys->i_rows ) / fmt_in.i_height; 
     416            if( p_sys->b_ar ) /* keep aspect ratio */ 
    398417            { 
    399                 fmt_out.i_width = ( fmt_out.i_height * fmt_in.i_width ) / fmt_in.i_height ; 
    400             } else { 
    401                 fmt_out.i_height = ( fmt_out.i_width * fmt_in.i_height ) / fmt_in.i_width ; 
     418                if( (float)fmt_out.i_width / (float)fmt_out.i_height 
     419                      > (float)fmt_in.i_width / (float)fmt_in.i_height ) 
     420                { 
     421                    fmt_out.i_width = ( fmt_out.i_height * fmt_in.i_width ) 
     422                                         / fmt_in.i_height ; 
     423                } 
     424                else 
     425                { 
     426                    fmt_out.i_height = ( fmt_out.i_width * fmt_in.i_height ) 
     427                                        / fmt_in.i_width ; 
     428                } 
     429             } 
     430 
     431            fmt_out.i_visible_width = fmt_out.i_width; 
     432            fmt_out.i_visible_height = fmt_out.i_height; 
     433 
     434#ifdef IMAGE_2PASSES 
     435            fmt_middle.i_chroma = fmt_in.i_chroma; 
     436            fmt_middle.i_visible_width = fmt_middle.i_width = fmt_out.i_width; 
     437            fmt_middle.i_visible_height = fmt_middle.i_height = fmt_out.i_height; 
     438 
     439            p_middle = image_Convert( p_sys->p_image2, p_pic->p_picture, 
     440                                      &fmt_in, &fmt_middle ); 
     441            if( !p_middle ) 
     442            { 
     443                msg_Warn( p_filter, "image resizing failed" ); 
     444                continue; 
    402445            } 
    403          } 
    404  
    405         fmt_out.i_visible_width = fmt_out.i_width; 
    406         fmt_out.i_visible_height = fmt_out.i_height; 
    407  
    408         fmt_middle.i_chroma = fmt_in.i_chroma; 
    409         fmt_middle.i_visible_width = fmt_middle.i_width = fmt_out.i_width; 
    410         fmt_middle.i_visible_height = fmt_middle.i_height = fmt_out.i_height; 
    411  
    412         p_middle = image_Convert( p_sys->p_image, 
    413             p_picture_vout->p_pic[i_index].p_picture, &fmt_in, &fmt_middle ); 
    414         if( !p_middle ) 
    415         { 
    416             msg_Err( p_filter, "image resizing failed" ); 
    417             p_filter->pf_sub_buffer_del( p_filter, p_spu ); 
    418             vlc_mutex_unlock( &p_picture_vout->lock ); 
    419             return NULL; 
    420         } 
    421  
    422         p_converted = image_Convert( p_sys->p_image2, 
    423                  p_middle, &fmt_middle, &fmt_out ); 
    424         if( !p_converted ) 
    425         { 
    426             msg_Err( p_filter, "image chroma convertion failed" ); 
    427             p_filter->pf_sub_buffer_del( p_filter, p_spu ); 
    428             vlc_mutex_unlock( &p_picture_vout->lock ); 
    429             return NULL; 
    430         } 
    431  
    432 /*        fprintf( stderr, "Converted %ix%i %4.4s\n", p_converted->format.i_width, p_converted->format.i_height, (char *)&p_converted->format.i_chroma);*/ 
    433  
    434  
    435         p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt_out); 
     446 
     447            p_converted = image_Convert( p_sys->p_image, p_middle, 
     448                                         &fmt_middle, &fmt_out ); 
     449            p_middle->pf_release( p_middle ); 
     450#else 
     451            p_converted = image_Convert( p_sys->p_image, p_pic->p_picture, 
     452                                         &fmt_in, &fmt_out ); 
     453#endif 
     454            if( !p_converted ) 
     455            { 
     456                msg_Warn( p_filter, "image chroma conversion failed" ); 
     457                continue; 
     458            } 
     459        } 
     460        else 
     461        { 
     462            p_converted = p_pic->p_picture; 
     463            p_converted->i_refcount++; 
     464            fmt_in.i_width = fmt_out.i_width = p_converted->format.i_width; 
     465            fmt_in.i_height = fmt_out.i_height = p_converted->format.i_height; 
     466            fmt_in.i_chroma = fmt_out.i_chroma = p_converted->format.i_chroma; 
     467            fmt_out.i_visible_width = fmt_out.i_width; 
     468            fmt_out.i_visible_height = fmt_out.i_height; 
     469        } 
     470 
     471        p_region = p_spu->pf_make_region( VLC_OBJECT(p_filter), &fmt_out, 
     472                                          p_converted ); 
    436473        if( !p_region ) 
    437474        { 
    438475            msg_Err( p_filter, "cannot allocate SPU region" ); 
    439476            p_filter->pf_sub_buffer_del( p_filter, p_spu ); 
    440             vlc_mutex_unlock( &p_picture_vout->lock ); 
     477            vlc_mutex_unlock( lockval.p_address ); 
    441478            return NULL; 
    442479        } 
    443480 
    444         if( p_sys->i_ar ) /* keep aspect ratio */ 
     481        /* HACK ALERT : let's fix the pointers to avoid picture duplication. 
     482         * This is necessary because p_region->picture is not a pointer 
     483         * as it ought to be. */ 
     484        if( !p_sys->b_keep ) 
     485        { 
     486            free( p_converted ); 
     487        } 
     488        else 
     489        { 
     490            /* Keep a pointer to the original picture (and its refcount...). */ 
     491            p_region->picture.p_sys = (picture_sys_t *)p_converted; 
     492            p_region->picture.pf_release = MosaicReleasePicture; 
     493        } 
     494 
     495        if( p_sys->b_ar || p_sys->b_keep ) /* keep aspect ratio */ 
    445496        { 
    446497            /* center the video in the dedicated rectangle */ 
    447498            p_region->i_x = p_sys->i_xoffset 
    448                             + i_col * ( p_sys->i_width / p_sys->i_cols ) 
    449                             + ( i_col * p_sys->i_vborder ) / p_sys->i_cols 
    450                         + ( fmt_in.i_width * 
    451             ( ( p_sys->i_width - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) 
    452               / p_sys->i_cols ) / fmt_in.i_width - fmt_out.i_width ) / 2; 
     499                        + i_col * ( p_sys->i_width / p_sys->i_cols ) 
     500                        + ( i_col * p_sys->i_vborder ) / p_sys->i_cols 
     501                        + ( ( ( p_sys->i_width 
     502                                - ( p_sys->i_cols - 1 ) * p_sys->i_vborder ) 
     503                            / p_sys->i_cols ) - fmt_out.i_width ) / 2; 
    453504            p_region->i_y = p_sys->i_yoffset 
    454505                        + i_row * ( p_sys->i_height / p_sys->i_rows ) 
    455506                        + ( i_row * p_sys->i_hborder ) / p_sys->i_rows 
    456                         + ( fmt_in.i_height * 
    457             ( ( p_sys->i_height - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) 
    458               / p_sys->i_rows ) / fmt_in.i_height - fmt_out.i_height ) / 2; 
    459         } else { 
     507                        + ( ( ( p_sys->i_height 
     508                                 - ( p_sys->i_rows - 1 ) * p_sys->i_hborder ) 
     509                            / p_sys->i_rows ) - fmt_out.i_height ) / 2; 
     510        } 
     511        else 
     512        { 
    460513            /* we don't have to center the video since it takes the 
    461514            whole rectangle area */ 
     
    468521        } 
    469522 
    470         if( p_region_prev == NULL ){ 
     523        if( p_region_prev == NULL ) 
     524        { 
    471525            p_spu->p_region = p_region; 
    472         } else { 
     526        } 
     527        else 
     528        { 
    473529            p_region_prev->p_next = p_region; 
    474530        } 
    475531 
    476532        p_region_prev = p_region; 
    477  
    478         vout_CopyPicture( p_filter, &p_region->picture, p_converted ); 
    479  
    480         p_middle->pf_release( p_middle ); 
    481         p_converted->pf_release( p_converted ); 
    482     } 
    483  
    484     vlc_mutex_unlock( &p_picture_vout->lock ); 
     533    } 
     534 
     535    vlc_mutex_unlock( lockval.p_address ); 
    485536 
    486537    return p_spu; 
     
    490541* Callback to update params on the fly 
    491542*****************************************************************************/ 
    492  
    493543static int MosaicCallback( vlc_object_t *p_this, char const *psz_var, 
    494544                            vlc_value_t oldval, vlc_value_t newval, 
     
    547597        { 
    548598            msg_Dbg( p_this, "Changing position method from %d (%s) to %d (%s)", 
    549                              p_sys->i_pos, ppsz_pos_descriptions[p_sys->i_pos], 
     599                             p_sys->i_position, ppsz_pos_descriptions[p_sys->i_position], 
    550600                             newval.i_int, ppsz_pos_descriptions[newval.i_int]); 
    551             p_sys->i_pos = newval.i_int; 
     601            p_sys->i_position = newval.i_int; 
    552602        } 
    553603    } 
     
    569619        { 
    570620            msg_Dbg( p_this, "Keep aspect ratio" ); 
    571             p_sys->i_ar = 1; 
     621            p_sys->b_ar = 1; 
    572622        } 
    573623        else 
    574624        { 
    575625            msg_Dbg( p_this, "Don't keep aspect ratio" ); 
    576             p_sys->i_ar = 0; 
     626            p_sys->b_ar = 0; 
    577627        } 
    578628    } 
  • modules/video_output/picture.c

    r97a71b4 rae42e9e  
    66 * 
    77 * Authors: Antoine Cellerier <dionoea@videolan.org> 
     8 *          Christophe Massiot <massiot@via.ecp.fr> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    3031 
    3132#include <vlc/vlc.h> 
    32 #include <vlc/intf.h> 
    3333#include <vlc/vout.h> 
    34 #include <vlc/aout.h> 
    35  
    36 #include <sys/types.h> 
    37 #ifndef WIN32 
    38 #   include <netinet/in.h>                            /* BSD: struct in_addr */ 
    39 #endif 
    40  
    41 /*********************************************************************** 
    42 
    43 ***********************************************************************/ 
     34 
     35#include "vlc_image.h" 
    &nb