~ubuntu-branches/ubuntu/lucid/vlc/lucid

« back to all changes in this revision

Viewing changes to modules/video_filter/deinterlace.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-11-12 15:29:11 UTC
  • mfrom: (3.5.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091112152911-skpz5ubpg18zjedp
Tags: 1.0.3-1ubuntu1
* Merge from Debian unstable (LP: #435524), remaining changes:
  - build against xulrunner-dev instead of iceape-dev
  - build against libx264-dev and install libx264 plugin
  - add Xb-Npp header to vlc package
  - recommend vlc-plugin-pulse for vlc
  - backport patch "402_increase_pulseaudio_score.diff"

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * deinterlace.c : deinterlacer plugin for vlc
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2000, 2001, 2002, 2003 the VideoLAN team
5
 
 * $Id: 3b86b7df18f43f6a9683c3a066550fee455e5dd5 $
 
5
 * $Id: ab0f9bbd2b9c0ef3714ce4a0aeb2009878831600 $
6
6
 *
7
7
 * Author: Sam Hocevar <sam@zoy.org>
8
8
 *
30
30
#endif
31
31
 
32
32
#include <errno.h>
 
33
#include <assert.h>
33
34
 
34
35
#ifdef HAVE_ALTIVEC_H
35
36
#   include <altivec.h>
53
54
#define DEINTERLACE_BOB     4
54
55
#define DEINTERLACE_LINEAR  5
55
56
#define DEINTERLACE_X       6
 
57
#define DEINTERLACE_YADIF   7
 
58
#define DEINTERLACE_YADIF2X 8
56
59
 
57
60
/*****************************************************************************
58
61
 * Local protypes
73
76
static void RenderBlend  ( vout_thread_t *, picture_t *, picture_t * );
74
77
static void RenderLinear ( vout_thread_t *, picture_t *, picture_t *, int );
75
78
static void RenderX      ( picture_t *, picture_t * );
 
79
static void RenderYadif  ( vout_thread_t *, picture_t *, picture_t *, int, int );
76
80
 
77
81
static void MergeGeneric ( void *, const void *, const void *, size_t );
78
82
#if defined(CAN_COMPILE_C_ALTIVEC)
118
122
#define FILTER_CFG_PREFIX "sout-deinterlace-"
119
123
 
120
124
static const char *const mode_list[] = {
121
 
    "discard", "blend", "mean", "bob", "linear", "x" };
 
125
    "discard", "blend", "mean", "bob", "linear", "x", "yadif", "yadif2x" };
122
126
static const char *const mode_list_text[] = {
123
 
    N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"), N_("Linear"), "X" };
 
127
    N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"), N_("Linear"), "X", "Yadif", "Yadif (2x)" };
124
128
 
125
129
vlc_module_begin ()
126
130
    set_description( N_("Deinterlacing video filter") )
158
162
 * This structure is part of the video output thread descriptor.
159
163
 * It describes the Deinterlace specific properties of an output thread.
160
164
 *****************************************************************************/
 
165
#define HISTORY_SIZE (3)
161
166
struct vout_sys_t
162
167
{
163
168
    int        i_mode;        /* Deinterlace mode */
173
178
 
174
179
    void (*pf_merge) ( void *, const void *, const void *, size_t );
175
180
    void (*pf_end_merge) ( void );
 
181
 
 
182
    /* Yadif */
 
183
    picture_t *pp_history[HISTORY_SIZE];
176
184
};
177
185
 
178
186
/*****************************************************************************
308
316
        p_vout->p_sys->b_double_rate = false;
309
317
        p_vout->p_sys->b_half_height = false;
310
318
    }
 
319
    else if( !strcmp( psz_method, "yadif" ) )
 
320
    {
 
321
        p_vout->p_sys->i_mode = DEINTERLACE_YADIF;
 
322
        p_vout->p_sys->b_double_rate = false;
 
323
        p_vout->p_sys->b_half_height = false;
 
324
    }
 
325
    else if( !strcmp( psz_method, "yadif2x" ) )
 
326
    {
 
327
        p_vout->p_sys->i_mode = DEINTERLACE_YADIF2X;
 
328
        p_vout->p_sys->b_double_rate = true;
 
329
        p_vout->p_sys->b_half_height = false;
 
330
    }
311
331
    else
312
332
    {
313
333
        const bool b_i422 = p_vout->render.i_chroma == VLC_FOURCC('I','4','2','2');
343
363
        case DEINTERLACE_MEAN:
344
364
        case DEINTERLACE_LINEAR:
345
365
        case DEINTERLACE_X:
 
366
        case DEINTERLACE_YADIF:
 
367
        case DEINTERLACE_YADIF2X:
346
368
            p_dst->i_chroma = VLC_FOURCC('I','4','2','2');
347
369
            break;
348
370
        default:
389
411
        return VLC_EGENERIC;
390
412
    }
391
413
 
 
414
    for( int i = 0; i < HISTORY_SIZE; i++ )
 
415
        p_vout->p_sys->pp_history[i] = NULL;
 
416
 
392
417
    vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
393
418
 
394
419
    vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
420
445
 
421
446
    var_DelCallback( p_vout, "deinterlace-mode", FilterCallback, NULL );
422
447
 
 
448
    for( int i = 0; i < HISTORY_SIZE; i++ )
 
449
    {
 
450
        if( p_sys->pp_history[i] )
 
451
            picture_Release( p_sys->pp_history[i] );
 
452
    }
 
453
 
423
454
    if( p_sys->p_vout )
424
455
    {
425
456
        vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
583
614
            RenderX( pp_outpic[0], p_pic );
584
615
            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
585
616
            break;
 
617
 
 
618
        case DEINTERLACE_YADIF:
 
619
            RenderYadif( p_vout, pp_outpic[0], p_pic, 0, 0 );
 
620
            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
 
621
            break;
 
622
 
 
623
        case DEINTERLACE_YADIF2X:
 
624
            RenderYadif( p_vout, pp_outpic[0], p_pic, 0, p_pic->b_top_field_first ? 0 : 1 );
 
625
            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
 
626
            RenderYadif( p_vout, pp_outpic[1], p_pic, 1, p_pic->b_top_field_first ? 1 : 0 );
 
627
            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );
 
628
            break;
586
629
    }
587
630
    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
588
631
}
1677
1720
}
1678
1721
 
1679
1722
/*****************************************************************************
 
1723
 * Yadif (Yet Another DeInterlacing Filter).
 
1724
 *****************************************************************************/
 
1725
/* */
 
1726
struct vf_priv_s {
 
1727
    /*
 
1728
     * 0: Output 1 frame for each frame.
 
1729
     * 1: Output 1 frame for each field.
 
1730
     * 2: Like 0 but skips spatial interlacing check.
 
1731
     * 3: Like 1 but skips spatial interlacing check.
 
1732
     *
 
1733
     * In vlc, only & 0x02 has meaning, as we do the & 0x01 ourself.
 
1734
     */
 
1735
    int mode;
 
1736
};
 
1737
 
 
1738
/* I am unsure it is the right one */
 
1739
typedef intptr_t x86_reg;
 
1740
 
 
1741
#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
 
1742
#define FFMAX(a,b)      __MAX(a,b)
 
1743
#define FFMAX3(a,b,c)   FFMAX(FFMAX(a,b),c)
 
1744
#define FFMIN(a,b)      __MIN(a,b)
 
1745
#define FFMIN3(a,b,c)   FFMIN(FFMIN(a,b),c)
 
1746
 
 
1747
/* yadif.h comes from vf_yadif.c of mplayer project */
 
1748
#include "yadif.h"
 
1749
 
 
1750
static void RenderYadif( vout_thread_t *p_vout, picture_t *p_dst, picture_t *p_src, int i_order, int i_field )
 
1751
{
 
1752
    vout_sys_t *p_sys = p_vout->p_sys;
 
1753
 
 
1754
    /* */
 
1755
    assert( i_order == 0 || i_order == 1 );
 
1756
    assert( i_field == 0 || i_field == 1 );
 
1757
 
 
1758
    if( i_order == 0 )
 
1759
    {
 
1760
        /* Duplicate the picture
 
1761
         * TODO when the vout rework is finished, picture_Hold() might be enough
 
1762
         * but becarefull, the pitches must match */
 
1763
        picture_t *p_dup = picture_New( p_src->format.i_chroma,
 
1764
                                        p_src->format.i_width,
 
1765
                                        p_src->format.i_height,
 
1766
                                        p_src->format.i_aspect );
 
1767
        if( p_dup )
 
1768
            picture_Copy( p_dup, p_src );
 
1769
 
 
1770
        /* Slide the history */
 
1771
        if( p_sys->pp_history[0] )
 
1772
            picture_Release( p_sys->pp_history[0]  );
 
1773
        for( int i = 1; i < HISTORY_SIZE; i++ )
 
1774
            p_sys->pp_history[i-1] = p_sys->pp_history[i];
 
1775
        p_sys->pp_history[HISTORY_SIZE-1] = p_dup;
 
1776
    }
 
1777
 
 
1778
    /* As the pitches must match, use ONLY pictures coming from picture_New()! */
 
1779
    picture_t *p_prev = p_sys->pp_history[0];
 
1780
    picture_t *p_cur  = p_sys->pp_history[1];
 
1781
    picture_t *p_next = p_sys->pp_history[2];
 
1782
 
 
1783
    /* Filter if we have all the pictures we need */
 
1784
    if( p_prev && p_cur && p_next )
 
1785
    {
 
1786
        /* */
 
1787
        void (*filter)(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity);
 
1788
#if defined(HAVE_YADIF_SSE2)
 
1789
        if( vlc_CPU() & CPU_CAPABILITY_SSE2 )
 
1790
            filter = yadif_filter_line_mmx2;
 
1791
        else
 
1792
#endif
 
1793
            filter = yadif_filter_line_c;
 
1794
 
 
1795
        for( int n = 0; n < p_dst->i_planes; n++ )
 
1796
        {
 
1797
            const plane_t *prevp = &p_prev->p[n];
 
1798
            const plane_t *curp  = &p_cur->p[n];
 
1799
            const plane_t *nextp = &p_next->p[n];
 
1800
            plane_t *dstp        = &p_dst->p[n];
 
1801
 
 
1802
            for( int y = 1; y < dstp->i_visible_lines - 1; y++ )
 
1803
            {
 
1804
                if( (y % 2) == i_field )
 
1805
                {
 
1806
                    vlc_memcpy( &dstp->p_pixels[y * dstp->i_pitch],
 
1807
                                &curp->p_pixels[y * curp->i_pitch], dstp->i_visible_pitch );
 
1808
                }
 
1809
                else
 
1810
                {
 
1811
                    struct vf_priv_s cfg;
 
1812
                    /* Spatial checks only when enough data */
 
1813
                    cfg.mode = (y >= 2 && y < dstp->i_visible_lines - 2) ? 0 : 2;
 
1814
 
 
1815
                    assert( prevp->i_pitch == curp->i_pitch && curp->i_pitch == nextp->i_pitch );
 
1816
                    filter( &cfg,
 
1817
                            &dstp->p_pixels[y * dstp->i_pitch],
 
1818
                            &prevp->p_pixels[y * prevp->i_pitch],
 
1819
                            &curp->p_pixels[y * curp->i_pitch],
 
1820
                            &nextp->p_pixels[y * nextp->i_pitch],
 
1821
                            dstp->i_visible_pitch,
 
1822
                            curp->i_pitch,
 
1823
                            (i_field ^ (i_order == i_field)) & 1 );
 
1824
                }
 
1825
 
 
1826
                /* We duplicate the first and last lines */
 
1827
                if( y == 1 )
 
1828
                    vlc_memcpy(&dstp->p_pixels[(y-1) * dstp->i_pitch], &dstp->p_pixels[y * dstp->i_pitch], dstp->i_pitch);
 
1829
                else if( y == dstp->i_visible_lines - 2 )
 
1830
                    vlc_memcpy(&dstp->p_pixels[(y+1) * dstp->i_pitch], &dstp->p_pixels[y * dstp->i_pitch], dstp->i_pitch);
 
1831
            }
 
1832
        }
 
1833
 
 
1834
        /* */
 
1835
        p_dst->date = (p_next->date - p_cur->date) * i_order / 2 + p_cur->date;
 
1836
    }
 
1837
    else
 
1838
    {
 
1839
        /* Fallback to something simple
 
1840
         * XXX it is wrong when we have 2 pictures, we should not output a picture */
 
1841
        RenderX( p_dst, p_src );
 
1842
    }
 
1843
}
 
1844
 
 
1845
/*****************************************************************************
1680
1846
 * FilterCallback: called when changing the deinterlace method on the fly.
1681
1847
 *****************************************************************************/
1682
1848
static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
1774
1940
        case DEINTERLACE_X:
1775
1941
            RenderX( p_pic_dst, p_pic );
1776
1942
            break;
 
1943
 
 
1944
        case DEINTERLACE_YADIF:
 
1945
            msg_Err( p_vout, "delaying frames is not supported yet" );
 
1946
            picture_Release( p_pic_dst );
 
1947
            picture_Release( p_pic );
 
1948
            return NULL;
 
1949
 
 
1950
        case DEINTERLACE_YADIF2X:
 
1951
            msg_Err( p_vout, "doubling the frame rate is not supported yet" );
 
1952
            picture_Release( p_pic_dst );
 
1953
            picture_Release( p_pic );
 
1954
            return NULL;
1777
1955
    }
1778
1956
 
1779
1957
    picture_CopyProperties( p_pic_dst, p_pic );