Esempio n. 1
0
File: cpu.c Progetto: 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;
}
Esempio n. 2
0
File: swscale.c Progetto: Tilka/vlc
/*****************************************************************************
 * Helpers
 *****************************************************************************/
static int GetSwsCpuMask(void)
{
    int i_sws_cpu = 0;

#if defined(__i386__) || defined(__x86_64__)
    if( vlc_CPU_MMX() )
        i_sws_cpu |= SWS_CPU_CAPS_MMX;
#if (LIBSWSCALE_VERSION_INT >= ((0<<16)+(5<<8)+0))
    if( vlc_CPU_MMXEXT() )
        i_sws_cpu |= SWS_CPU_CAPS_MMX2;
#endif
    if( vlc_CPU_3dNOW() )
        i_sws_cpu |= SWS_CPU_CAPS_3DNOW;
#elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__)
    if( vlc_CPU_ALTIVEC() )
        i_sws_cpu |= SWS_CPU_CAPS_ALTIVEC;
#endif

    return i_sws_cpu;
}
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;
    }
}
Esempio n. 4
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;
    uint32_t i_accel = 0;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGV )
        return VLC_EGENERIC;

    /* Select onl recognized original format (standard mpeg video) */
    switch( p_dec->fmt_in.i_original_fourcc )
    {
    case VLC_FOURCC('m','p','g','1'):
    case VLC_FOURCC('m','p','g','2'):
    case VLC_FOURCC('m','p','g','v'):
    case VLC_FOURCC('P','I','M','1'):
    case VLC_FOURCC('h','d','v','2'):
        break;
    default:
        if( p_dec->fmt_in.i_original_fourcc )
            return VLC_EGENERIC;
        break;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(*p_sys)) ) == NULL )
        return VLC_ENOMEM;

    /* Initialize the thread properties */
    p_sys->p_mpeg2dec = NULL;
    p_sys->p_synchro  = NULL;
    p_sys->p_info     = NULL;
    p_sys->i_current_pts  = 0;
    p_sys->i_previous_pts = 0;
    p_sys->i_current_dts  = 0;
    p_sys->i_previous_dts = 0;
    p_sys->i_sar_num = 0;
    p_sys->i_sar_den = 0;
    p_sys->b_garbage_pic = false;
    p_sys->b_slice_i  = false;
    p_sys->b_second_field = false;
    p_sys->b_skip     = false;
    p_sys->b_preroll = false;
    DpbInit( p_dec );

    p_sys->i_cc_pts = 0;
    p_sys->i_cc_dts = 0;
    p_sys->i_cc_flags = 0;
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
    p_dec->pf_get_cc = GetCc;
    cc_Init( &p_sys->cc );
#endif
    p_sys->p_gop_user_data = NULL;
    p_sys->i_gop_user_data = 0;

#if defined( __i386__ ) || defined( __x86_64__ )
    if( vlc_CPU_MMX() )
        i_accel |= MPEG2_ACCEL_X86_MMX;
    if( vlc_CPU_3dNOW() )
        i_accel |= MPEG2_ACCEL_X86_3DNOW;
    if( vlc_CPU_MMXEXT() )
        i_accel |= MPEG2_ACCEL_X86_MMXEXT;
#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
    if( vlc_CPU_ALTIVEC() )
        i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;

#elif defined(__arm__)
# ifdef MPEG2_ACCEL_ARM
    i_accel |= MPEG2_ACCEL_ARM;
# endif
# ifdef MPEG2_ACCEL_ARM_NEON
    if( vlc_CPU_ARM_NEON() )
        i_accel |= MPEG2_ACCEL_ARM_NEON;
# endif

    /* TODO: sparc */
#else
    /* If we do not know this CPU, trust libmpeg2's feature detection */
    i_accel = MPEG2_ACCEL_DETECT;

#endif

    /* Set CPU acceleration features */
    mpeg2_accel( i_accel );

    /* Initialize decoder */
    p_sys->p_mpeg2dec = mpeg2_init();
    if( p_sys->p_mpeg2dec == NULL)
    {
        msg_Err( p_dec, "mpeg2_init() failed" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );

    p_dec->pf_decode_video = DecodeBlock;
    p_dec->fmt_out.i_cat = VIDEO_ES;
    p_dec->fmt_out.i_codec = 0;

    return VLC_SUCCESS;
}