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

« back to all changes in this revision

Viewing changes to modules/codec/ffmpeg/video_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
 
 * video filter: video filter doing chroma conversion and resizing
3
 
 *               using the ffmpeg library
4
 
 *****************************************************************************
5
 
 * Copyright (C) 1999-2001 the VideoLAN team
6
 
 * $Id: a6d66457c73a31abbe49d51c6f0ef10b6a57234b $
7
 
 *
8
 
 * Authors: Gildas Bazin <gbazin@videolan.org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
 
 *****************************************************************************/
24
 
 
25
 
/*****************************************************************************
26
 
 * Preamble
27
 
 *****************************************************************************/
28
 
#include <vlc/vlc.h>
29
 
#include <vlc/decoder.h>
30
 
#include "vlc_filter.h"
31
 
 
32
 
/* ffmpeg header */
33
 
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
34
 
#   include <libavcodec/avcodec.h>
35
 
#elif defined(HAVE_FFMPEG_AVCODEC_H)
36
 
#   include <ffmpeg/avcodec.h>
37
 
#else
38
 
#   include <avcodec.h>
39
 
#endif
40
 
 
41
 
#include "ffmpeg.h"
42
 
 
43
 
void E_(InitLibavcodec) ( vlc_object_t *p_object );
44
 
static int CheckInit( filter_t *p_filter );
45
 
static picture_t *Process( filter_t *p_filter, picture_t *p_pic );
46
 
static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic );
47
 
 
48
 
/*****************************************************************************
49
 
 * filter_sys_t : filter descriptor
50
 
 *****************************************************************************/
51
 
struct filter_sys_t
52
 
{
53
 
    vlc_bool_t b_resize;
54
 
    vlc_bool_t b_convert;
55
 
    vlc_bool_t b_resize_first;
56
 
    vlc_bool_t b_enable_croppadd;
57
 
 
58
 
    es_format_t fmt_in;
59
 
    int i_src_ffmpeg_chroma;
60
 
    es_format_t fmt_out;
61
 
    int i_dst_ffmpeg_chroma;
62
 
 
63
 
    AVPicture tmp_pic;
64
 
    ImgReSampleContext *p_rsc;
65
 
};
66
 
 
67
 
 
68
 
/*****************************************************************************
69
 
 * OpenFilterEx: common code to OpenFilter and OpenCropPadd
70
 
 *****************************************************************************/
71
 
static int OpenFilterEx( vlc_object_t *p_this, vlc_bool_t b_enable_croppadd )
72
 
{
73
 
    filter_t *p_filter = (filter_t*)p_this;
74
 
    filter_sys_t *p_sys;
75
 
    vlc_bool_t b_convert, b_resize;
76
 
 
77
 
    /* Check if we can handle that formats */
78
 
    if( E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma ) < 0 ||
79
 
        E_(GetFfmpegChroma)( p_filter->fmt_out.video.i_chroma ) < 0 )
80
 
    {
81
 
        return VLC_EGENERIC;
82
 
    }
83
 
 
84
 
    b_resize =
85
 
        p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ||
86
 
        p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height;
87
 
 
88
 
    if ( b_enable_croppadd ) 
89
 
    {
90
 
        b_resize = b_resize ||
91
 
            p_filter->fmt_in.video.i_visible_width != p_filter->fmt_in.video.i_width ||
92
 
            p_filter->fmt_in.video.i_visible_height != p_filter->fmt_in.video.i_height ||
93
 
            p_filter->fmt_in.video.i_x_offset != 0 ||
94
 
            p_filter->fmt_in.video.i_y_offset != 0 ||
95
 
            p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
96
 
            p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
97
 
            p_filter->fmt_out.video.i_x_offset != 0 ||
98
 
            p_filter->fmt_out.video.i_y_offset != 0;
99
 
    }
100
 
 
101
 
    b_convert =
102
 
        p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma;
103
 
 
104
 
    if( !b_resize && !b_convert )
105
 
    {
106
 
        /* Nothing to do */
107
 
        return VLC_EGENERIC;
108
 
    }
109
 
 
110
 
    /* Allocate the memory needed to store the decoder's structure */
111
 
    if( ( p_filter->p_sys = p_sys =
112
 
          (filter_sys_t *)malloc(sizeof(filter_sys_t)) ) == NULL )
113
 
    {
114
 
        msg_Err( p_filter, "out of memory" );
115
 
        return VLC_EGENERIC;
116
 
    }
117
 
 
118
 
    /* Misc init */
119
 
    p_sys->p_rsc = NULL;
120
 
    p_sys->b_enable_croppadd = b_enable_croppadd;
121
 
    p_sys->i_src_ffmpeg_chroma =
122
 
        E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma );
123
 
    p_sys->i_dst_ffmpeg_chroma =
124
 
        E_(GetFfmpegChroma)( p_filter->fmt_out.video.i_chroma );
125
 
    p_filter->pf_video_filter = Process;
126
 
    es_format_Init( &p_sys->fmt_in, 0, 0 );
127
 
    es_format_Init( &p_sys->fmt_out, 0, 0 );
128
 
 
129
 
    /* Dummy alloc, will be reallocated in CheckInit */
130
 
    avpicture_alloc( &p_sys->tmp_pic, p_sys->i_src_ffmpeg_chroma,
131
 
                     p_filter->fmt_out.video.i_width,
132
 
                     p_filter->fmt_out.video.i_height );
133
 
 
134
 
    if( CheckInit( p_filter ) != VLC_SUCCESS )
135
 
    {   
136
 
        if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
137
 
        avpicture_free( &p_sys->tmp_pic );
138
 
        free( p_sys );
139
 
        return VLC_EGENERIC;
140
 
    }
141
 
 
142
 
    msg_Dbg( p_filter, "input: %ix%i %4.4s -> %ix%i %4.4s",
143
 
             p_filter->fmt_in.video.i_width, p_filter->fmt_in.video.i_height,
144
 
             (char *)&p_filter->fmt_in.video.i_chroma,
145
 
             p_filter->fmt_out.video.i_width, p_filter->fmt_out.video.i_height,
146
 
             (char *)&p_filter->fmt_out.video.i_chroma );
147
 
 
148
 
    /* libavcodec needs to be initialized for some chroma conversions */
149
 
    E_(InitLibavcodec)(p_this);
150
 
 
151
 
    return VLC_SUCCESS;
152
 
}
153
 
 
154
 
/*****************************************************************************
155
 
 * OpenFilter: probe the filter and return score
156
 
 *****************************************************************************/
157
 
int E_(OpenFilter)( vlc_object_t *p_this )
158
 
{
159
 
    return OpenFilterEx( p_this, VLC_FALSE );
160
 
}
161
 
 
162
 
/*****************************************************************************
163
 
 * OpenCropPadd: probe the filter and return score
164
 
 *****************************************************************************/
165
 
int E_(OpenCropPadd)( vlc_object_t *p_this )
166
 
{
167
 
    return OpenFilterEx( p_this, VLC_TRUE );
168
 
}
169
 
 
170
 
 
171
 
/*****************************************************************************
172
 
 * CloseFilter: clean up the filter
173
 
 *****************************************************************************/
174
 
void E_(CloseFilter)( vlc_object_t *p_this )
175
 
{
176
 
    filter_t *p_filter = (filter_t*)p_this;
177
 
    filter_sys_t *p_sys = p_filter->p_sys;
178
 
 
179
 
    if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
180
 
    avpicture_free( &p_sys->tmp_pic );
181
 
 
182
 
    free( p_sys );
183
 
}
184
 
 
185
 
/*****************************************************************************
186
 
 * CheckInit: Initialise filter when necessary
187
 
 *****************************************************************************/
188
 
static int CheckInit( filter_t *p_filter )
189
 
{
190
 
    filter_sys_t *p_sys = p_filter->p_sys;
191
 
    vlc_bool_t b_change;
192
 
    int i_croptop=0;
193
 
    int i_cropbottom=0;
194
 
    int i_cropleft=0;
195
 
    int i_cropright=0;
196
 
    int i_paddtop=0;
197
 
    int i_paddbottom=0;
198
 
    int i_paddleft=0;
199
 
    int i_paddright=0;
200
 
 
201
 
 
202
 
    b_change= p_filter->fmt_in.video.i_width != p_sys->fmt_in.video.i_width ||
203
 
        p_filter->fmt_in.video.i_height != p_sys->fmt_in.video.i_height ||
204
 
        p_filter->fmt_out.video.i_width != p_sys->fmt_out.video.i_width ||
205
 
        p_filter->fmt_out.video.i_height != p_sys->fmt_out.video.i_height;
206
 
 
207
 
    if ( p_sys->b_enable_croppadd )
208
 
    {
209
 
        b_change = b_change ||
210
 
            p_filter->fmt_in.video.i_y_offset != p_sys->fmt_in.video.i_y_offset ||
211
 
            p_filter->fmt_in.video.i_x_offset != p_sys->fmt_in.video.i_x_offset ||
212
 
            p_filter->fmt_in.video.i_visible_width != p_sys->fmt_in.video.i_visible_width ||
213
 
            p_filter->fmt_in.video.i_visible_height != p_sys->fmt_in.video.i_visible_height ||
214
 
            p_filter->fmt_out.video.i_y_offset != p_sys->fmt_out.video.i_y_offset ||
215
 
            p_filter->fmt_out.video.i_x_offset != p_sys->fmt_out.video.i_x_offset ||
216
 
            p_filter->fmt_out.video.i_visible_width != p_sys->fmt_out.video.i_visible_width ||
217
 
            p_filter->fmt_out.video.i_visible_height != p_sys->fmt_out.video.i_visible_height;
218
 
    }
219
 
 
220
 
    if ( b_change )
221
 
    {
222
 
        if( p_sys->p_rsc ) img_resample_close( p_sys->p_rsc );
223
 
        p_sys->p_rsc = 0;
224
 
 
225
 
        p_sys->b_convert =
226
 
          p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma;
227
 
 
228
 
        p_sys->b_resize =
229
 
          p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ||
230
 
          p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height;
231
 
 
232
 
        p_sys->b_resize_first =
233
 
          p_filter->fmt_in.video.i_width * p_filter->fmt_in.video.i_height >
234
 
          p_filter->fmt_out.video.i_width * p_filter->fmt_out.video.i_height;
235
 
 
236
 
        if( p_sys->b_resize &&
237
 
            p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUV420P &&
238
 
            p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUVJ420P &&
239
 
            p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUV420P &&
240
 
            p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUVJ420P )
241
 
        {
242
 
            msg_Err( p_filter, "img_resample_init only deals with I420" );
243
 
            return VLC_EGENERIC;
244
 
        }
245
 
        else if( p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUV420P &&
246
 
                 p_sys->i_src_ffmpeg_chroma != PIX_FMT_YUVJ420P )
247
 
        {
248
 
            p_sys->b_resize_first = VLC_FALSE;
249
 
        }
250
 
        else if( p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUV420P &&
251
 
                 p_sys->i_dst_ffmpeg_chroma != PIX_FMT_YUVJ420P )
252
 
        {
253
 
            p_sys->b_resize_first = VLC_TRUE;
254
 
        }
255
 
 
256
 
        if ( p_sys->b_enable_croppadd )
257
 
        {
258
 
            p_sys->b_resize = p_sys->b_resize ||
259
 
                p_filter->fmt_in.video.i_visible_width != p_filter->fmt_in.video.i_width ||
260
 
                p_filter->fmt_in.video.i_visible_height != p_filter->fmt_in.video.i_height ||
261
 
                p_filter->fmt_in.video.i_x_offset != 0 ||
262
 
                p_filter->fmt_in.video.i_y_offset != 0 ||
263
 
                p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
264
 
                p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
265
 
                p_filter->fmt_out.video.i_x_offset != 0 ||
266
 
                p_filter->fmt_out.video.i_y_offset != 0;
267
 
        }
268
 
 
269
 
        if( p_sys->b_resize )
270
 
        {
271
 
            if ( p_sys->b_enable_croppadd )
272
 
            {
273
 
                i_croptop=p_filter->fmt_in.video.i_y_offset;
274
 
                i_cropbottom=p_filter->fmt_in.video.i_height
275
 
                                       - p_filter->fmt_in.video.i_visible_height
276
 
                                       - p_filter->fmt_in.video.i_y_offset;
277
 
                i_cropleft=p_filter->fmt_in.video.i_x_offset;
278
 
                i_cropright=p_filter->fmt_in.video.i_width
279
 
                                      - p_filter->fmt_in.video.i_visible_width
280
 
                                      - p_filter->fmt_in.video.i_x_offset;
281
 
 
282
 
 
283
 
                i_paddtop=p_filter->fmt_out.video.i_y_offset;
284
 
                i_paddbottom=p_filter->fmt_out.video.i_height
285
 
                                       - p_filter->fmt_out.video.i_visible_height
286
 
                                       - p_filter->fmt_out.video.i_y_offset;
287
 
                i_paddleft=p_filter->fmt_out.video.i_x_offset;
288
 
                i_paddright=p_filter->fmt_out.video.i_width
289
 
                                      - p_filter->fmt_out.video.i_visible_width
290
 
                                      - p_filter->fmt_out.video.i_x_offset;
291
 
            }
292
 
 
293
 
#if LIBAVCODEC_BUILD >= 4708
294
 
            p_sys->p_rsc = img_resample_full_init( 
295
 
                               p_filter->fmt_out.video.i_width,
296
 
                               p_filter->fmt_out.video.i_height,
297
 
                               p_filter->fmt_in.video.i_width,
298
 
                               p_filter->fmt_in.video.i_height,
299
 
                               i_croptop,i_cropbottom,
300
 
                               i_cropleft,i_cropright,
301
 
                               i_paddtop,i_paddbottom,
302
 
                               i_paddleft,i_paddright );
303
 
#else
304
 
            p_sys->p_rsc = img_resample_full_init( 
305
 
                               p_filter->fmt_out.video.i_width - i_paddleft - i_paddright,
306
 
                               p_filter->fmt_out.video.i_height - i_paddtop - i_paddbottom,
307
 
                               p_filter->fmt_in.video.i_width,
308
 
                               p_filter->fmt_in.video.i_height,
309
 
                               i_croptop,i_cropbottom,
310
 
                               i_cropleft,i_cropright );
311
 
#endif
312
 
            msg_Dbg( p_filter, "input: %ix%i -> %ix%i",
313
 
                p_filter->fmt_out.video.i_width,
314
 
                p_filter->fmt_out.video.i_height,
315
 
                p_filter->fmt_in.video.i_width,
316
 
                p_filter->fmt_in.video.i_height);
317
 
 
318
 
            if( !p_sys->p_rsc )
319
 
            {
320
 
                msg_Err( p_filter, "img_resample_init failed" );
321
 
                return VLC_EGENERIC;
322
 
            }
323
 
        }
324
 
 
325
 
        avpicture_free( &p_sys->tmp_pic );
326
 
 
327
 
        if( p_sys->b_resize_first )
328
 
        {
329
 
            /* Resizing then conversion */
330
 
            avpicture_alloc( &p_sys->tmp_pic, p_sys->i_src_ffmpeg_chroma,
331
 
                             p_filter->fmt_out.video.i_width,
332
 
                             p_filter->fmt_out.video.i_height );
333
 
        }
334
 
        else
335
 
        {
336
 
            /* Conversion then resizing */
337
 
            avpicture_alloc( &p_sys->tmp_pic, p_sys->i_dst_ffmpeg_chroma,
338
 
                             p_filter->fmt_in.video.i_width,
339
 
                             p_filter->fmt_in.video.i_height );
340
 
        }
341
 
 
342
 
        p_sys->fmt_in = p_filter->fmt_in;
343
 
        p_sys->fmt_out = p_filter->fmt_out;
344
 
    }
345
 
 
346
 
    return VLC_SUCCESS;
347
 
}
348
 
 
349
 
/* fill padd code from ffmpeg */
350
 
static int padcolor[3] = { 16, 128, 128 };
351
 
 
352
 
/* Expects img to be yuv420 */
353
 
static void fill_pad_region( AVPicture* img, int height, int width,
354
 
        int padtop, int padbottom, int padleft, int padright, int *color ) 
355
 
{
356
 
    int i, y, shift;
357
 
    uint8_t *optr;
358
 
 
359
 
    for ( i = 0; i < 3; i++ ) 
360
 
    {
361
 
        shift = ( i == 0 ) ? 0 : 1;
362
 
 
363
 
        if ( padtop || padleft ) 
364
 
        {
365
 
            memset( img->data[i], color[i], ( ( ( img->linesize[i] * padtop ) +
366
 
                            padleft ) >> shift) );
367
 
        }
368
 
 
369
 
        if ( padleft || padright ) 
370
 
        {
371
 
            optr = img->data[i] + ( img->linesize[i] * ( padtop >> shift ) ) +
372
 
                ( img->linesize[i] - ( padright >> shift ) );
373
 
 
374
 
            for ( y = 0; y < ( ( height - ( padtop + padbottom ) ) >> shift ); y++ ) 
375
 
            {
376
 
                memset( optr, color[i], ( padleft + padright ) >> shift );
377
 
                optr += img->linesize[i];
378
 
            }
379
 
        }
380
 
 
381
 
        if (padbottom) 
382
 
        {
383
 
            optr = img->data[i] + ( img->linesize[i] * ( ( height - padbottom ) >> shift ) );
384
 
            memset( optr, color[i], ( ( img->linesize[i] * padbottom ) >> shift ) );
385
 
        }
386
 
    }
387
 
}
388
 
 
389
 
#if LIBAVCODEC_BUILD < 4708
390
 
 
391
 
/* Workaround, because old libavcodec doesnt know how to padd */
392
 
 
393
 
static void img_resample_padd( ImgReSampleContext *s, AVPicture *output, 
394
 
        const AVPicture *input, int padtop, int padleft )
395
 
{
396
 
    AVPicture nopadd_pic = *output;
397
 
 
398
 
    /* shift out top and left padding for old ffmpeg */
399
 
    nopadd_pic.data[0] += ( nopadd_pic.linesize[0] * padtop + padleft );
400
 
    nopadd_pic.data[1] += ( nopadd_pic.linesize[1] * padtop + padleft ) >> 1;
401
 
    nopadd_pic.data[2] += ( nopadd_pic.linesize[2] * padtop + padleft ) >> 1;
402
 
    img_resample( s, &nopadd_pic, input );
403
 
}
404
 
#endif
405
 
 
406
 
 
407
 
 
408
 
/*****************************************************************************
409
 
 * Do the processing here
410
 
 *****************************************************************************/
411
 
static picture_t *Process( filter_t *p_filter, picture_t *p_pic )
412
 
{
413
 
    filter_sys_t *p_sys = p_filter->p_sys;
414
 
    AVPicture src_pic, dest_pic;
415
 
    AVPicture *p_src, *p_dst;
416
 
    picture_t *p_pic_dst;
417
 
    int i;
418
 
 
419
 
    /* Check if format properties changed */
420
 
    if( CheckInit( p_filter ) != VLC_SUCCESS ) return 0;
421
 
 
422
 
    /* Request output picture */
423
 
    p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
424
 
    if( !p_pic_dst )
425
 
    {
426
 
        msg_Warn( p_filter, "can't get output picture" );
427
 
        if( p_pic->pf_release )
428
 
            p_pic->pf_release( p_pic );
429
 
        return NULL;
430
 
    }
431
 
 
432
 
    /* Prepare the AVPictures for the conversion */
433
 
    for( i = 0; i < p_pic->i_planes; i++ )
434
 
    {
435
 
        src_pic.data[i] = p_pic->p[i].p_pixels;
436
 
        src_pic.linesize[i] = p_pic->p[i].i_pitch;
437
 
    }
438
 
    for( i = 0; i < p_pic_dst->i_planes; i++ )
439
 
    {
440
 
        dest_pic.data[i] = p_pic_dst->p[i].p_pixels;
441
 
        dest_pic.linesize[i] = p_pic_dst->p[i].i_pitch;
442
 
    }
443
 
 
444
 
    /* Special cases */
445
 
    if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') ||
446
 
        p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','U','9') )
447
 
    {
448
 
        /* Invert U and V */
449
 
        src_pic.data[1] = p_pic->p[2].p_pixels;
450
 
        src_pic.data[2] = p_pic->p[1].p_pixels;
451
 
    }
452
 
    if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','1','2') ||
453
 
        p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','U','9') )
454
 
    {
455
 
        /* Invert U and V */
456
 
        dest_pic.data[1] = p_pic_dst->p[2].p_pixels;
457
 
        dest_pic.data[2] = p_pic_dst->p[1].p_pixels;
458
 
    }
459
 
    if( p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 )
460
 
        if( p_filter->fmt_in.video.i_bmask == 0x00ff0000 )
461
 
            p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24;
462
 
 
463
 
    p_src = &src_pic;
464
 
 
465
 
    if( p_sys->b_resize && p_sys->p_rsc )
466
 
    {
467
 
        p_dst = &dest_pic;
468
 
        if( p_sys->b_resize_first )
469
 
        {
470
 
            if( p_sys->b_convert ) p_dst = &p_sys->tmp_pic;
471
 
 
472
 
#if LIBAVCODEC_BUILD >= 4708
473
 
            img_resample( p_sys->p_rsc, p_dst, p_src );
474
 
#else        
475
 
            if ( p_sys->b_enable_croppadd )
476
 
            {
477
 
                img_resample_padd( p_sys->p_rsc, p_dst, p_src, 
478
 
                    p_filter->fmt_out.video.i_y_offset, 
479
 
                    p_filter->fmt_out.video.i_x_offset );
480
 
            } 
481
 
            else 
482
 
            {
483
 
                img_resample( p_sys->p_rsc, p_dst, p_src );
484
 
            }
485
 
#endif
486
 
 
487
 
            if (p_sys->b_enable_croppadd)
488
 
            {
489
 
                if (p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
490
 
                    p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
491
 
                    p_filter->fmt_out.video.i_x_offset != 0 ||
492
 
                    p_filter->fmt_out.video.i_y_offset != 0)
493
 
                {
494
 
                    fill_pad_region(p_dst, p_filter->fmt_out.video.i_height,
495
 
                                    p_filter->fmt_out.video.i_width,
496
 
                                    p_filter->fmt_out.video.i_y_offset,
497
 
                                    p_filter->fmt_out.video.i_height
498
 
                                      - p_filter->fmt_out.video.i_visible_height
499
 
                                      - p_filter->fmt_out.video.i_y_offset,
500
 
                                    p_filter->fmt_out.video.i_x_offset,
501
 
                                    p_filter->fmt_out.video.i_width
502
 
                                      - p_filter->fmt_out.video.i_visible_width
503
 
                                      - p_filter->fmt_out.video.i_x_offset,
504
 
                                    padcolor);
505
 
                }
506
 
            }
507
 
 
508
 
            p_src = p_dst;
509
 
        }
510
 
    }
511
 
 
512
 
    if( p_sys->b_convert )
513
 
    {
514
 
        video_format_t *p_fmt = &p_filter->fmt_out.video;
515
 
        p_dst = &dest_pic;
516
 
        if( p_sys->b_resize && !p_sys->b_resize_first )
517
 
        {
518
 
            p_dst = &p_sys->tmp_pic;
519
 
            p_fmt = &p_filter->fmt_in.video;
520
 
        }
521
 
 
522
 
        img_convert( p_dst, p_sys->i_dst_ffmpeg_chroma,
523
 
                     p_src, p_sys->i_src_ffmpeg_chroma,
524
 
                     p_fmt->i_width, p_fmt->i_height );
525
 
 
526
 
        p_src = p_dst;
527
 
    }
528
 
 
529
 
    if( p_sys->b_resize && !p_sys->b_resize_first && p_sys->p_rsc )
530
 
    {
531
 
        p_dst = &dest_pic;
532
 
 
533
 
#if LIBAVCODEC_BUILD >= 4708
534
 
        img_resample( p_sys->p_rsc, p_dst, p_src );
535
 
#else
536
 
        if ( p_sys->b_enable_croppadd )
537
 
        {
538
 
            img_resample_padd( p_sys->p_rsc, p_dst, p_src, 
539
 
                p_filter->fmt_out.video.i_y_offset, 
540
 
                p_filter->fmt_out.video.i_x_offset );
541
 
        } 
542
 
        else 
543
 
        {
544
 
            img_resample( p_sys->p_rsc, p_dst, p_src );
545
 
        }
546
 
#endif
547
 
 
548
 
        if (p_sys->b_enable_croppadd)
549
 
        {
550
 
            if (p_filter->fmt_out.video.i_visible_width != p_filter->fmt_out.video.i_width ||
551
 
                p_filter->fmt_out.video.i_visible_height != p_filter->fmt_out.video.i_height ||
552
 
                p_filter->fmt_out.video.i_x_offset != 0 ||
553
 
                p_filter->fmt_out.video.i_y_offset != 0)
554
 
            {
555
 
                fill_pad_region(p_dst, p_filter->fmt_out.video.i_height,
556
 
                                p_filter->fmt_out.video.i_width,
557
 
                                p_filter->fmt_out.video.i_y_offset,
558
 
                                p_filter->fmt_out.video.i_height
559
 
                                  - p_filter->fmt_out.video.i_visible_height
560
 
                                  - p_filter->fmt_out.video.i_y_offset,
561
 
                                p_filter->fmt_out.video.i_x_offset,
562
 
                                p_filter->fmt_out.video.i_width
563
 
                                  - p_filter->fmt_out.video.i_visible_width
564
 
                                  - p_filter->fmt_out.video.i_x_offset,
565
 
                                padcolor);
566
 
            }
567
 
        }
568
 
    }
569
 
 
570
 
    /* Special case for RV32 -> YUVA */
571
 
    if( !p_sys->b_resize &&
572
 
        p_filter->fmt_in.video.i_chroma == VLC_FOURCC('R','V','3','2') &&
573
 
        p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','V','A') )
574
 
    {
575
 
        uint8_t *p_src = p_pic->p[0].p_pixels;
576
 
        int i_src_pitch = p_pic->p[0].i_pitch;
577
 
        uint8_t *p_dst = p_pic_dst->p[3].p_pixels;
578
 
        int i_dst_pitch = p_pic_dst->p[3].i_pitch;
579
 
        uint32_t l,j;
580
 
 
581
 
        for( l = 0; l < p_filter->fmt_out.video.i_height; l++ )
582
 
        {
583
 
            for( j = 0; j < p_filter->fmt_out.video.i_width; j++ )
584
 
            {
585
 
              p_dst[j] = p_src[j*4+3];
586
 
            }
587
 
            p_src += i_src_pitch;
588
 
            p_dst += i_dst_pitch;
589
 
        }
590
 
    }
591
 
    else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','V','A') )
592
 
    {
593
 
        /* Special case for YUVA */
594
 
        memset( p_pic_dst->p[3].p_pixels, 0xFF,
595
 
                p_pic_dst->p[3].i_pitch * p_pic_dst->p[3].i_lines );
596
 
    }
597
 
 
598
 
    p_pic_dst->date = p_pic->date;
599
 
    p_pic_dst->b_force = p_pic->b_force;
600
 
    p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
601
 
    p_pic_dst->b_progressive = p_pic->b_progressive;
602
 
    p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
603
 
 
604
 
    if( p_pic->pf_release )
605
 
        p_pic->pf_release( p_pic );
606
 
    return p_pic_dst;
607
 
}
608
 
 
609
 
/*****************************************************************************
610
 
 * OpenDeinterlace: probe the filter and return score
611
 
 *****************************************************************************/
612
 
int E_(OpenDeinterlace)( vlc_object_t *p_this )
613
 
{
614
 
    filter_t *p_filter = (filter_t*)p_this;
615
 
    filter_sys_t *p_sys;
616
 
 
617
 
    /* Check if we can handle that formats */
618
 
    if( E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma ) < 0 )
619
 
    {
620
 
        return VLC_EGENERIC;
621
 
    }
622
 
 
623
 
    /* Allocate the memory needed to store the decoder's structure */
624
 
    if( ( p_filter->p_sys = p_sys =
625
 
          (filter_sys_t *)malloc(sizeof(filter_sys_t)) ) == NULL )
626
 
    {
627
 
        msg_Err( p_filter, "out of memory" );
628
 
        return VLC_EGENERIC;
629
 
    }
630
 
 
631
 
    /* Misc init */
632
 
    p_sys->i_src_ffmpeg_chroma =
633
 
        E_(GetFfmpegChroma)( p_filter->fmt_in.video.i_chroma );
634
 
    p_filter->pf_video_filter = Deinterlace;
635
 
 
636
 
    msg_Dbg( p_filter, "deinterlacing" );
637
 
 
638
 
    /* libavcodec needs to be initialized for some chroma conversions */
639
 
    E_(InitLibavcodec)(p_this);
640
 
 
641
 
    return VLC_SUCCESS;
642
 
}
643
 
 
644
 
/*****************************************************************************
645
 
 * CloseDeinterlace: clean up the filter
646
 
 *****************************************************************************/
647
 
void E_(CloseDeinterlace)( vlc_object_t *p_this )
648
 
{
649
 
    filter_t *p_filter = (filter_t*)p_this;
650
 
    filter_sys_t *p_sys = p_filter->p_sys;
651
 
 
652
 
    free( p_sys );
653
 
}
654
 
 
655
 
/*****************************************************************************
656
 
 * Do the processing here
657
 
 *****************************************************************************/
658
 
static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
659
 
{
660
 
    filter_sys_t *p_sys = p_filter->p_sys;
661
 
    AVPicture src_pic, dest_pic;
662
 
    picture_t *p_pic_dst;
663
 
    int i;
664
 
 
665
 
    /* Request output picture */
666
 
    p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
667
 
    if( !p_pic_dst )
668
 
    {
669
 
        msg_Warn( p_filter, "can't get output picture" );
670
 
        return NULL;
671
 
    }
672
 
 
673
 
    /* Prepare the AVPictures for the conversion */
674
 
    for( i = 0; i < p_pic->i_planes; i++ )
675
 
    {
676
 
        src_pic.data[i] = p_pic->p[i].p_pixels;
677
 
        src_pic.linesize[i] = p_pic->p[i].i_pitch;
678
 
    }
679
 
    for( i = 0; i < p_pic_dst->i_planes; i++ )
680
 
    {
681
 
        dest_pic.data[i] = p_pic_dst->p[i].p_pixels;
682
 
        dest_pic.linesize[i] = p_pic_dst->p[i].i_pitch;
683
 
    }
684
 
 
685
 
    avpicture_deinterlace( &dest_pic, &src_pic, p_sys->i_src_ffmpeg_chroma,
686
 
                           p_filter->fmt_in.video.i_width,
687
 
                           p_filter->fmt_in.video.i_height );
688
 
 
689
 
    p_pic_dst->date = p_pic->date;
690
 
    p_pic_dst->b_force = p_pic->b_force;
691
 
    p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
692
 
    p_pic_dst->b_progressive = VLC_TRUE;
693
 
    p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
694
 
 
695
 
    if( p_pic->pf_release )
696
 
        p_pic->pf_release( p_pic );
697
 
    return p_pic_dst;
698
 
}