~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/video_filter/swscale/filter.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 * filter.c: video scaling module using the swscale library
3
 
 *****************************************************************************
4
 
 * Copyright (C) 2003 the VideoLAN team
5
 
 * $Id: e3c50ecacc4fc2d77bc3f91dd67d06ff6aa9d06b $
6
 
 *
7
 
 * Author: Gildas Bazin <gbazin@videolan.org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
 
 *****************************************************************************/
23
 
 
24
 
/*****************************************************************************
25
 
 * Preamble
26
 
 *****************************************************************************/
27
 
#include <vlc/vlc.h>
28
 
#include <vlc/decoder.h>
29
 
#include "vlc_filter.h"
30
 
 
31
 
#include "common.h"
32
 
#include "swscale.h"
33
 
 
34
 
void *( *swscale_fast_memcpy )( void *, const void *, size_t );
35
 
 
36
 
/*****************************************************************************
37
 
 * filter_sys_t : filter descriptor
38
 
 *****************************************************************************/
39
 
struct filter_sys_t
40
 
{
41
 
    struct SwsContext *ctx;
42
 
    SwsFilter *p_src_filter;
43
 
    SwsFilter *p_dst_filter;
44
 
    int i_cpu_mask, i_sws_flags;
45
 
 
46
 
    es_format_t fmt_in;
47
 
    es_format_t fmt_out;
48
 
};
49
 
 
50
 
/****************************************************************************
51
 
 * Local prototypes
52
 
 ****************************************************************************/
53
 
static int  OpenFilter ( vlc_object_t * );
54
 
static void CloseFilter( vlc_object_t * );
55
 
 
56
 
static picture_t *Filter( filter_t *, picture_t * );
57
 
static int CheckInit( filter_t * );
58
 
static int GetSwscaleChroma( vlc_fourcc_t );
59
 
 
60
 
/*****************************************************************************
61
 
 * Module descriptor
62
 
 *****************************************************************************/
63
 
#define MODE_TEXT N_("Scaling mode")
64
 
#define MODE_LONGTEXT N_("Scaling mode to use.")
65
 
 
66
 
static int pi_mode_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
67
 
static char *ppsz_mode_descriptions[] =
68
 
{ N_("Fast bilinear"), N_("Bilinear"), N_("Bicubic (good quality)"),
69
 
  N_("Experimental"), N_("Nearest neighbour (bad quality)"),
70
 
  N_("Area"), N_("Luma bicubic / chroma bilinear"), N_("Gauss"),
71
 
  N_("SincR"), N_("Lanczos"), N_("Bicubic spline") };
72
 
 
73
 
vlc_module_begin();
74
 
    set_description( _("Video scaling filter") );
75
 
    set_capability( "video filter2", 1000 );
76
 
    set_category( CAT_VIDEO );
77
 
    set_subcategory( SUBCAT_VIDEO_VFILTER );
78
 
    set_callbacks( OpenFilter, CloseFilter );
79
 
 
80
 
    add_integer( "swscale-mode", 0, NULL, MODE_TEXT, MODE_LONGTEXT, VLC_TRUE );
81
 
        change_integer_list( pi_mode_values, ppsz_mode_descriptions, 0 );
82
 
vlc_module_end();
83
 
 
84
 
/*****************************************************************************
85
 
 * OpenFilter: probe the filter and return score
86
 
 *****************************************************************************/
87
 
static int OpenFilter( vlc_object_t *p_this )
88
 
{
89
 
    filter_t *p_filter = (filter_t*)p_this;
90
 
    filter_sys_t *p_sys;
91
 
    vlc_value_t val;
92
 
 
93
 
    unsigned int i_fmt_in, i_fmt_out;
94
 
    int i_sws_mode;
95
 
 
96
 
    float sws_lum_gblur = 0.0, sws_chr_gblur = 0.0;
97
 
    int sws_chr_vshift = 0, sws_chr_hshift = 0;
98
 
    float sws_chr_sharpen = 0.0, sws_lum_sharpen = 0.0;
99
 
 
100
 
    /* Supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR24,
101
 
     * BGR16, BGR15, RGB32, RGB24, Y8/Y800, YVU9/IF09 */
102
 
    if( !(i_fmt_in = GetSwscaleChroma(p_filter->fmt_in.video.i_chroma)) )
103
 
    {
104
 
        return VLC_EGENERIC;
105
 
    }
106
 
 
107
 
    /* Supported output formats: YV12, I420/IYUV, YUY2, UYVY,
108
 
     * {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09 */
109
 
    if( !(i_fmt_out = GetSwscaleChroma(p_filter->fmt_out.video.i_chroma)) )
110
 
    {
111
 
        return VLC_EGENERIC;
112
 
    }
113
 
 
114
 
    /* Allocate the memory needed to store the decoder's structure */
115
 
    if( ( p_filter->p_sys = p_sys =
116
 
          (filter_sys_t *)malloc(sizeof(filter_sys_t)) ) == NULL )
117
 
    {
118
 
        msg_Err( p_filter, "out of memory" );
119
 
        return VLC_EGENERIC;
120
 
    }
121
 
 
122
 
    swscale_fast_memcpy = p_filter->p_vlc->pf_memcpy;
123
 
 
124
 
    /* Set CPU capabilities */
125
 
    p_sys->i_cpu_mask = 0;
126
 
    if( p_filter->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
127
 
    {
128
 
        p_sys->i_cpu_mask |= SWS_CPU_CAPS_MMX;
129
 
    }
130
 
    if( p_filter->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
131
 
    {
132
 
        p_sys->i_cpu_mask |= SWS_CPU_CAPS_MMX2;
133
 
    }
134
 
    if( p_filter->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
135
 
    {
136
 
        p_sys->i_cpu_mask |= SWS_CPU_CAPS_3DNOW;
137
 
    }
138
 
    if( p_filter->p_libvlc->i_cpu & CPU_CAPABILITY_ALTIVEC )
139
 
    {
140
 
        p_sys->i_cpu_mask |= SWS_CPU_CAPS_ALTIVEC;
141
 
    }
142
 
 
143
 
    var_Create( p_filter, "swscale-mode", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
144
 
    var_Get( p_filter, "swscale-mode", &val );
145
 
    i_sws_mode = val.i_int;
146
 
 
147
 
    switch( i_sws_mode )
148
 
    {
149
 
    case 0:  p_sys->i_sws_flags = SWS_FAST_BILINEAR; break;
150
 
    case 1:  p_sys->i_sws_flags = SWS_BILINEAR; break;
151
 
    case 2:  p_sys->i_sws_flags = SWS_BICUBIC; break;
152
 
    case 3:  p_sys->i_sws_flags = SWS_X; break;
153
 
    case 4:  p_sys->i_sws_flags = SWS_POINT; break;
154
 
    case 5:  p_sys->i_sws_flags = SWS_AREA; break;
155
 
    case 6:  p_sys->i_sws_flags = SWS_BICUBLIN; break;
156
 
    case 7:  p_sys->i_sws_flags = SWS_GAUSS; break;
157
 
    case 8:  p_sys->i_sws_flags = SWS_SINC; break;
158
 
    case 9:  p_sys->i_sws_flags = SWS_LANCZOS; break;
159
 
    case 10: p_sys->i_sws_flags = SWS_SPLINE; break;
160
 
    default: p_sys->i_sws_flags = SWS_FAST_BILINEAR; i_sws_mode = 0; break;
161
 
    }
162
 
 
163
 
    p_sys->p_src_filter = 0; p_sys->p_dst_filter = 0;
164
 
    p_sys->p_src_filter =
165
 
        sws_getDefaultFilter( sws_lum_gblur, sws_chr_gblur,
166
 
                              sws_lum_sharpen, sws_chr_sharpen,
167
 
                              sws_chr_hshift, sws_chr_vshift, 0 );
168
 
 
169
 
    /* Misc init */
170
 
    p_sys->ctx = NULL;
171
 
    p_filter->pf_video_filter = Filter;
172
 
    es_format_Init( &p_sys->fmt_in, 0, 0 );
173
 
    es_format_Init( &p_sys->fmt_out, 0, 0 );
174
 
 
175
 
    if( CheckInit( p_filter ) != VLC_SUCCESS )
176
 
    {
177
 
        if( p_sys->p_src_filter ) sws_freeFilter( p_sys->p_src_filter );
178
 
        free( p_sys );
179
 
        return VLC_EGENERIC;
180
 
    }
181
 
 
182
 
    msg_Dbg( p_filter, "%ix%i chroma: %4.4s -> %ix%i chroma: %4.4s",
183
 
             p_filter->fmt_in.video.i_width, p_filter->fmt_in.video.i_height,
184
 
             (char *)&p_filter->fmt_in.video.i_chroma,
185
 
             p_filter->fmt_out.video.i_width, p_filter->fmt_out.video.i_height,
186
 
             (char *)&p_filter->fmt_out.video.i_chroma );
187
 
 
188
 
    if( p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ||
189
 
        p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height )
190
 
    {
191
 
        msg_Dbg( p_filter, "scaling mode: %s",
192
 
                 ppsz_mode_descriptions[i_sws_mode] );
193
 
    }
194
 
 
195
 
    return VLC_SUCCESS;
196
 
}
197
 
 
198
 
/*****************************************************************************
199
 
 * CloseFilter: clean up the filter
200
 
 *****************************************************************************/
201
 
static void CloseFilter( vlc_object_t *p_this )
202
 
{
203
 
    filter_t *p_filter = (filter_t*)p_this;
204
 
    filter_sys_t *p_sys = p_filter->p_sys;
205
 
 
206
 
    if( p_sys->ctx ) sws_freeContext( p_sys->ctx );
207
 
    if( p_sys->p_src_filter ) sws_freeFilter( p_sys->p_src_filter );
208
 
    free( p_sys );
209
 
}
210
 
 
211
 
/*****************************************************************************
212
 
 * CheckInit: Initialise filter when necessary
213
 
 *****************************************************************************/
214
 
static int CheckInit( filter_t *p_filter )
215
 
{
216
 
    filter_sys_t *p_sys = p_filter->p_sys;
217
 
 
218
 
    if( p_filter->fmt_in.video.i_width != p_sys->fmt_in.video.i_width ||
219
 
        p_filter->fmt_in.video.i_height != p_sys->fmt_in.video.i_height ||
220
 
        p_filter->fmt_out.video.i_width != p_sys->fmt_out.video.i_width ||
221
 
        p_filter->fmt_out.video.i_height != p_sys->fmt_out.video.i_height )
222
 
    {
223
 
        unsigned int i_fmt_in, i_fmt_out;
224
 
 
225
 
        if( !(i_fmt_in = GetSwscaleChroma(p_filter->fmt_in.video.i_chroma)) ||
226
 
            !(i_fmt_out = GetSwscaleChroma(p_filter->fmt_out.video.i_chroma)) )
227
 
        {
228
 
            msg_Err( p_filter, "format not supported" );
229
 
            return VLC_EGENERIC;
230
 
        }
231
 
 
232
 
        if( p_sys->ctx ) sws_freeContext( p_sys->ctx );
233
 
 
234
 
        p_sys->ctx =
235
 
            sws_getContext( p_filter->fmt_in.video.i_width,
236
 
                            p_filter->fmt_in.video.i_height, i_fmt_in,
237
 
                            p_filter->fmt_out.video.i_width,
238
 
                            p_filter->fmt_out.video.i_height, i_fmt_out,
239
 
                            p_sys->i_sws_flags | p_sys->i_cpu_mask,
240
 
                            p_sys->p_src_filter, p_sys->p_dst_filter );
241
 
        if( !p_sys->ctx )
242
 
        {
243
 
            msg_Err( p_filter, "could not init SwScaler" );
244
 
            return VLC_EGENERIC;
245
 
        }
246
 
 
247
 
        p_sys->fmt_in = p_filter->fmt_in;
248
 
        p_sys->fmt_out = p_filter->fmt_out;
249
 
    }
250
 
 
251
 
    return VLC_SUCCESS;
252
 
}
253
 
 
254
 
/****************************************************************************
255
 
 * Filter: the whole thing
256
 
 ****************************************************************************
257
 
 * This function is called just after the thread is launched.
258
 
 ****************************************************************************/
259
 
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
260
 
{
261
 
    filter_sys_t *p_sys = p_filter->p_sys;
262
 
    uint8_t *src[3]; int src_stride[3];
263
 
    uint8_t *dst[3]; int dst_stride[3];
264
 
    picture_t *p_pic_dst;
265
 
    int i_plane;
266
 
    int i_nb_planes = p_pic->i_planes;
267
 
 
268
 
    /* Check if format properties changed */
269
 
    if( CheckInit( p_filter ) != VLC_SUCCESS ) return 0;
270
 
 
271
 
    /* Request output picture */
272
 
    p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
273
 
    if( !p_pic_dst )
274
 
    {
275
 
        msg_Warn( p_filter, "can't get output picture" );
276
 
        return NULL;
277
 
    }
278
 
 
279
 
    if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','V','A') )
280
 
    {
281
 
        i_nb_planes = 3;
282
 
        memset( p_pic_dst->p[3].p_pixels, 0xff, p_filter->fmt_out.video.i_height
283
 
                                                 * p_pic_dst->p[3].i_pitch );
284
 
    }
285
 
 
286
 
    for( i_plane = 0; i_plane < __MIN(3, p_pic->i_planes); i_plane++ )
287
 
    {
288
 
        src[i_plane] = p_pic->p[i_plane].p_pixels;
289
 
        src_stride[i_plane] = p_pic->p[i_plane].i_pitch;
290
 
    }
291
 
    for( i_plane = 0; i_plane < __MIN(3, i_nb_planes); i_plane++ )
292
 
    {
293
 
        dst[i_plane] = p_pic_dst->p[i_plane].p_pixels;
294
 
        dst_stride[i_plane] = p_pic_dst->p[i_plane].i_pitch;
295
 
    }
296
 
 
297
 
    sws_scale_ordered( p_sys->ctx, src, src_stride,
298
 
                       0, p_filter->fmt_in.video.i_height,
299
 
                       dst, dst_stride );
300
 
 
301
 
    p_pic_dst->date = p_pic->date;
302
 
    p_pic_dst->b_force = p_pic->b_force;
303
 
    p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
304
 
    p_pic_dst->b_progressive = p_pic->b_progressive;
305
 
    p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
306
 
 
307
 
    if( p_pic->pf_release )
308
 
        p_pic->pf_release( p_pic );
309
 
    return p_pic_dst;
310
 
}
311
 
 
312
 
/*****************************************************************************
313
 
 * Chroma fourcc -> ffmpeg_id mapping
314
 
 *****************************************************************************/
315
 
static struct
316
 
{
317
 
    vlc_fourcc_t  i_chroma;
318
 
    unsigned int  i_swscale_chroma;
319
 
 
320
 
} chroma_table[] =
321
 
{
322
 
    /* Planar YUV formats */
323
 
    { VLC_FOURCC('Y','V','1','2'), IMGFMT_YV12 },
324
 
    { VLC_FOURCC('I','4','2','0'), IMGFMT_I420 },
325
 
    { VLC_FOURCC('I','Y','U','V'), IMGFMT_IYUV },
326
 
    { VLC_FOURCC('I','4','4','4'), IMGFMT_444P },
327
 
    { VLC_FOURCC('Y','U','V','A'), IMGFMT_444P },
328
 
    { VLC_FOURCC('I','4','2','2'), IMGFMT_422P },
329
 
    { VLC_FOURCC('I','4','1','1'), IMGFMT_411P },
330
 
#if 0
331
 
    { VLC_FOURCC('Y','U','V','P'), IMGFMT_Y800 },
332
 
#endif
333
 
 
334
 
    /* Packed YUV formats */
335
 
    { VLC_FOURCC('U','Y','V','Y'), IMGFMT_UYVY },
336
 
    { VLC_FOURCC('Y','U','Y','2'), IMGFMT_YUY2 },
337
 
 
338
 
    /* Packed RGB formats */
339
 
    { VLC_FOURCC('R','V','1','5'), IMGFMT_RGB15 },
340
 
    { VLC_FOURCC('R','V','1','6'), IMGFMT_RGB16 },
341
 
    { VLC_FOURCC('R','V','2','4'), IMGFMT_RGB24 },
342
 
    { VLC_FOURCC('R','V','3','2'), IMGFMT_RGB32 },
343
 
    { VLC_FOURCC('G','R','E','Y'), IMGFMT_RGB8 },
344
 
 
345
 
    {0}
346
 
};
347
 
 
348
 
static int GetSwscaleChroma( vlc_fourcc_t i_chroma )
349
 
{
350
 
    int i;
351
 
 
352
 
    for( i = 0; chroma_table[i].i_chroma != 0; i++ )
353
 
    {
354
 
        if( chroma_table[i].i_chroma == i_chroma )
355
 
            return chroma_table[i].i_swscale_chroma;
356
 
    }
357
 
    return 0;
358
 
}