示例#1
0
文件: cpu.c 项目: jamesbates/vlc
/**
 * Maps CPU capabilities computed by VLC to libav DSP mask.
 */
unsigned GetVlcDspMask( void )
{
    unsigned mask = 0;

#if defined (__i386__) || defined (__x86_64__)
    if( !vlc_CPU_MMX() )
        mask |= AV_CPU_FLAG_MMX;
    if( !vlc_CPU_MMXEXT() )
        mask |= AV_CPU_FLAG_MMX2;
    if( !vlc_CPU_3dNOW() )
        mask |= AV_CPU_FLAG_3DNOW;
    if( !vlc_CPU_SSE() )
        mask |= AV_CPU_FLAG_SSE;
    if( !vlc_CPU_SSE2() )
        mask |= AV_CPU_FLAG_SSE2;
# ifdef AV_CPU_FLAG_SSE3
    if( !vlc_CPU_SSE3() )
        mask |= AV_CPU_FLAG_SSE3;
# endif
# ifdef AV_CPU_FLAG_SSSE3
    if( !vlc_CPU_SSSE3() )
        mask |= AV_CPU_FLAG_SSSE3;
# endif
# ifdef AV_CPU_FLAG_SSE4
    if( !vlc_CPU_SSE4_1() )
        mask |= AV_CPU_FLAG_SSE4;
# endif
# ifdef AV_CPU_FLAG_SSE42
    if( !vlc_CPU_SSE4_2() )
        mask |= AV_CPU_FLAG_SSE42;
# endif
# ifdef AV_CPU_FLAG_AVX
    if( !vlc_CPU_AVX() )
        mask |= AV_CPU_FLAG_AVX;
# endif
# ifdef AV_CPU_FLAG_XOP
    if( !vlc_CPU_XOP() )
        mask |= AV_CPU_FLAG_XOP;
# endif
# ifdef AV_CPU_FLAG_FMA4
    if( !vlc_CPU_FMA4() )
        mask |= AV_CPU_FLAG_FMA4;
# endif
#endif

#if defined (__ppc__) || defined (__ppc64__) || defined (__powerpc__)
    if( !vlc_CPU_ALTIVEC() )
        mask |= AV_CPU_FLAG_ALTIVEC;
#endif

#if defined ( __arm__)
#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(29<<8)+0)
    if( !vlc_CPU_ARM_NEON() )
        mask |= AV_CPU_FLAG_NEON;
#endif
#endif

    return mask;
}
示例#2
0
文件: gradfun.c 项目: IAPark/vlc
static int Open(vlc_object_t *object)
{
    filter_t *filter = (filter_t *)object;
    const vlc_fourcc_t fourcc = filter->fmt_in.video.i_chroma;

    const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription(fourcc);
    if (!chroma || chroma->plane_count < 3 || chroma->pixel_size != 1) {
        msg_Err(filter, "Unsupported chroma (%4.4s)", (char*)&fourcc);
        return VLC_EGENERIC;
    }

    filter_sys_t *sys = malloc(sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    vlc_mutex_init(&sys->lock);
    sys->chroma   = chroma;
    sys->strength = var_CreateGetFloatCommand(filter,   CFG_PREFIX "strength");
    sys->radius   = var_CreateGetIntegerCommand(filter, CFG_PREFIX "radius");
    var_AddCallback(filter, CFG_PREFIX "strength", Callback, NULL);
    var_AddCallback(filter, CFG_PREFIX "radius",   Callback, NULL);
    sys->cfg.buf = NULL;

    struct vf_priv_s *cfg = &sys->cfg;
    cfg->thresh      = 0.0;
    cfg->radius      = 0;
    cfg->buf         = NULL;

#if HAVE_SSE2 && HAVE_6REGS
    if (vlc_CPU_SSE2())
        cfg->blur_line = blur_line_sse2;
    else
#endif
        cfg->blur_line   = blur_line_c;
#if HAVE_SSSE3
    if (vlc_CPU_SSSE3())
        cfg->filter_line = filter_line_ssse3;
    else
#endif
#if HAVE_MMX2
    if (vlc_CPU_MMXEXT())
        cfg->filter_line = filter_line_mmx2;
    else
#endif
        cfg->filter_line = filter_line_c;

    filter->p_sys           = sys;
    filter->pf_video_filter = Filter;
    return VLC_SUCCESS;
}
int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
                 int i_order, int i_field )
{
    VLC_UNUSED(p_src);

    filter_sys_t *p_sys = p_filter->p_sys;

    /* */
    assert( i_order >= 0 && i_order <= 2 ); /* 2 = soft field repeat */
    assert( i_field == 0 || i_field == 1 );

    /* As the pitches must match, use ONLY pictures coming from picture_New()! */
    picture_t *p_prev = p_sys->pp_history[0];
    picture_t *p_cur  = p_sys->pp_history[1];
    picture_t *p_next = p_sys->pp_history[2];

    /* Account for soft field repeat.

       The "parity" parameter affects the algorithm like this (from yadif.h):
       uint8_t *prev2= parity ? prev : cur ;
       uint8_t *next2= parity ? cur  : next;

       The original parity expression that was used here is:
       (i_field ^ (i_order == i_field)) & 1

       Truth table:
       i_field = 0, i_order = 0  => 1
       i_field = 1, i_order = 1  => 0
       i_field = 1, i_order = 0  => 1
       i_field = 0, i_order = 1  => 0

       => equivalent with e.g.  (1 - i_order)  or  (i_order + 1) % 2

       Thus, in a normal two-field frame,
             parity 1 = first field  (i_order == 0)
             parity 0 = second field (i_order == 1)

       Now, with three fields, where the third is a copy of the first,
             i_order = 0  =>  parity 1 (as usual)
             i_order = 1  =>  due to the repeat, prev = cur, but also next = cur.
                              Because in such a case there is no motion
                              (otherwise field repeat makes no sense),
                              we don't actually need to invoke Yadif's filter().
                              Thus, set "parity" to 2, and use this to bypass
                              the filter.
             i_order = 2  =>  parity 0 (as usual)
    */
    int yadif_parity;
    if( p_cur  &&  p_cur->i_nb_fields > 2 )
        yadif_parity = (i_order + 1) % 3; /* 1, *2*, 0; where 2 is a special
                                             value meaning "bypass filter". */
    else
        yadif_parity = (i_order + 1) % 2; /* 1, 0 */

    /* Filter if we have all the pictures we need */
    if( p_prev && p_cur && p_next )
    {
        /* */
        void (*filter)(uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next,
                       int w, int prefs, int mrefs, int parity, int mode);

#if defined(HAVE_YADIF_SSSE3)
        if( vlc_CPU_SSSE3() )
            filter = yadif_filter_line_ssse3;
        else
#endif
#if defined(HAVE_YADIF_SSE2)
        if( vlc_CPU_SSE2() )
            filter = yadif_filter_line_sse2;
        else
#endif
#if defined(HAVE_YADIF_MMX)
        if( vlc_CPU_MMX() )
            filter = yadif_filter_line_mmx;
        else
#endif
            filter = yadif_filter_line_c;

        if( p_sys->chroma->pixel_size == 2 )
            filter = (void (__cdecl *)(uint8_t *,uint8_t *,uint8_t *,uint8_t *,int,int,int,int,int))yadif_filter_line_c_16bit;			// sunqueen modify

        for( int n = 0; n < p_dst->i_planes; n++ )
        {
            const plane_t *prevp = &p_prev->p[n];
            const plane_t *curp  = &p_cur->p[n];
            const plane_t *nextp = &p_next->p[n];
            plane_t *dstp        = &p_dst->p[n];

            for( int y = 1; y < dstp->i_visible_lines - 1; y++ )
            {
                if( (y % 2) == i_field  ||  yadif_parity == 2 )
                {
                    memcpy( &dstp->p_pixels[y * dstp->i_pitch],
                                &curp->p_pixels[y * curp->i_pitch], dstp->i_visible_pitch );
                }
                else
                {
                    int mode;
                    /* Spatial checks only when enough data */
                    mode = (y >= 2 && y < dstp->i_visible_lines - 2) ? 0 : 2;

                    assert( prevp->i_pitch == curp->i_pitch && curp->i_pitch == nextp->i_pitch );
                    filter( &dstp->p_pixels[y * dstp->i_pitch],
                            &prevp->p_pixels[y * prevp->i_pitch],
                            &curp->p_pixels[y * curp->i_pitch],
                            &nextp->p_pixels[y * nextp->i_pitch],
                            dstp->i_visible_pitch,
                            y < dstp->i_visible_lines - 2  ? curp->i_pitch : -curp->i_pitch,
                            y  - 1  ?  -curp->i_pitch : curp->i_pitch,
                            yadif_parity,
                            mode );
                }

                /* We duplicate the first and last lines */
                if( y == 1 )
                    memcpy(&dstp->p_pixels[(y-1) * dstp->i_pitch],
                               &dstp->p_pixels[ y    * dstp->i_pitch],
                               dstp->i_pitch);
                else if( y == dstp->i_visible_lines - 2 )
                    memcpy(&dstp->p_pixels[(y+1) * dstp->i_pitch],
                               &dstp->p_pixels[ y    * dstp->i_pitch],
                               dstp->i_pitch);
            }
        }

        p_sys->i_frame_offset = 1; /* p_cur will be rendered at next frame, too */

        return VLC_SUCCESS;
    }
    else if( !p_prev && !p_cur && p_next )
    {
        /* NOTE: For the first frame, we use the default frame offset
                 as set by Open() or SetFilterMethod(). It is always 0. */

        /* FIXME not good as it does not use i_order/i_field */
        RenderX( p_dst, p_next );
        return VLC_SUCCESS;
    }
    else
    {
        p_sys->i_frame_offset = 1; /* p_cur will be rendered at next frame */

        return VLC_EGENERIC;
    }
}