Example #1
0
File: cpu.c Project: 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;
}
/*****************************************************************************
 * OpenFilter:
 *****************************************************************************/
static int OpenFilter( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;

    if (!vlc_CPU_ARM_NEON())
        return VLC_EGENERIC;

    audio_format_t fmt_in  = p_filter->fmt_in.audio;
    audio_format_t fmt_out = p_filter->fmt_out.audio;

    fmt_in.i_format = p_filter->fmt_in.i_codec;
    fmt_out.i_format = p_filter->fmt_out.i_codec;

    if( fmt_in.i_format != VLC_CODEC_FL32 ||
            fmt_in.i_format != fmt_out.i_format ||
            fmt_in.i_rate != fmt_out.i_rate )
    {
        return VLC_EGENERIC;
    }

    if( fmt_in.i_physical_channels == fmt_out.i_physical_channels &&
            fmt_in.i_original_channels == fmt_out.i_original_channels )
    {
        return VLC_EGENERIC;
    }

    const bool b_input_7 = (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_7_0;
    const bool b_input_5 = ( (fmt_in.i_physical_channels & AOUT_CHANS_5_0) == AOUT_CHANS_5_0 ||
                             (fmt_in.i_physical_channels & AOUT_CHANS_5_0_MIDDLE) == AOUT_CHANS_5_0_MIDDLE );
    const bool b_input_4 =  (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_4_CENTER_REAR;
    const bool b_input_3 = (fmt_in.i_physical_channels & ~AOUT_CHAN_LFE) == AOUT_CHANS_3_0;

    const bool b_output_1 = fmt_out.i_physical_channels == AOUT_CHAN_CENTER;
    const bool b_output_2 = fmt_out.i_physical_channels == AOUT_CHANS_2_0;
    const bool b_output_4 = fmt_out.i_physical_channels == AOUT_CHANS_4_0;

    /* Only conversion to Mono, Stereo and 4.0 right now */
    /* Only from 7/7.1/5/5.1/3/3.1/2.0
     * XXX 5.X rear and middle are handled the same way */

    TRY_FILTER(7,2)
    TRY_FILTER(5,2)
    TRY_FILTER(4,2)
    TRY_FILTER(3,2)
    TRY_FILTER(7,1)
    TRY_FILTER(5,1)
    TRY_FILTER(7,4)
    TRY_FILTER(5,4)

    return VLC_EGENERIC;
}
Example #3
0
static int Open (vlc_object_t *obj)
{
    filter_t *filter = (filter_t *)obj;

    if (!vlc_CPU_ARM_NEON())
        return VLC_EGENERIC;

    if (((filter->fmt_in.video.i_width | filter->fmt_in.video.i_height) & 1)
     || (filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
     || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
        return VLC_EGENERIC;

    switch (filter->fmt_out.video.i_chroma)
    {
        case VLC_CODEC_RGB16:
            switch (filter->fmt_in.video.i_chroma)
            {
                case VLC_CODEC_I420:
                    filter->pf_video_filter = I420_RV16_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        case VLC_CODEC_RGB32:
            if(        filter->fmt_out.video.i_rmask != 0x000000ff
                    || filter->fmt_out.video.i_gmask != 0x0000ff00
                    || filter->fmt_out.video.i_bmask != 0x00ff0000 )
                return VLC_EGENERIC;

            switch (filter->fmt_in.video.i_chroma)
            {
                case VLC_CODEC_I420:
                    filter->pf_video_filter = I420_RGBA_Filter;
                    break;
                case VLC_CODEC_YV12:
                    filter->pf_video_filter = YV12_RGBA_Filter;
                    break;
                case VLC_CODEC_NV21:
                    filter->pf_video_filter = NV21_RGBA_Filter;
                    break;
                case VLC_CODEC_NV12:
                    filter->pf_video_filter = NV12_RGBA_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        default:
            return VLC_EGENERIC;
    }

    //precompute some values for the C version
    /*const int coefY  = (int)(1.164 * 32768 + 0.5);
    const int coefRV = (int)(1.793 * 32768 + 0.5);
    const int coefGU = (int)(0.213 * 32768 + 0.5);
    const int coefGV = (int)(0.533 * 32768 + 0.5);
    const int coefBU = (int)(2.113 * 32768 + 0.5);
    for (int i=0; i<256; ++i)
    {
        CoefY[i] = coefY * (i-16) + 16384;
        CoefRV[i] = coefRV*(i-128);
        CoefGU[i] = -coefGU*(i-128);
        CoefGV[i] = -coefGV*(i-128);
        CoefBU[i] = coefBU*(i-128);
    }*/

    msg_Dbg(filter, "%4.4s(%dx%d) to %4.4s(%dx%d)",
            (char*)&filter->fmt_in.video.i_chroma, filter->fmt_in.video.i_width, filter->fmt_in.video.i_height,
            (char*)&filter->fmt_out.video.i_chroma, filter->fmt_out.video.i_width, filter->fmt_out.video.i_height);

    return VLC_SUCCESS;
}
Example #4
0
static int Open (vlc_object_t *obj)
{
    filter_t *filter = (filter_t *)obj;

    if (!vlc_CPU_ARM_NEON())
        return VLC_EGENERIC;
    if ((filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
     || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
        return VLC_EGENERIC;

    switch (filter->fmt_in.video.i_chroma)
    {
        /* Planar to packed */
        case VLC_CODEC_I420:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I420_YUYV_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I420_UYVY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I420_YVYU_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I420_VYUY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        case VLC_CODEC_YV12:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I420_YVYU_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I420_VYUY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I420_YUYV_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I420_UYVY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        case VLC_CODEC_I422:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_YUYV:
                    filter->pf_video_filter = I422_YUYV_Filter;
                    break;
                case VLC_CODEC_UYVY:
                    filter->pf_video_filter = I422_UYVY_Filter;
                    break;
                case VLC_CODEC_YVYU:
                    filter->pf_video_filter = I422_YVYU_Filter;
                    break;
                case VLC_CODEC_VYUY:
                    filter->pf_video_filter = I422_VYUY_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }
            break;

        /* Packed to planar */
        case VLC_CODEC_YUYV:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = YUYV_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        case VLC_CODEC_UYVY:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = UYVY_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        case VLC_CODEC_YVYU:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = YVYU_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }


        case VLC_CODEC_VYUY:
            switch (filter->fmt_out.video.i_chroma)
            {
                case VLC_CODEC_I422:
                    filter->pf_video_filter = VYUY_I422_Filter;
                    break;
                default:
                    return VLC_EGENERIC;
            }

        default:
            return VLC_EGENERIC;
    }
    return VLC_SUCCESS;
}
Example #5
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;
}
Example #6
0
int Open( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t*)p_this;
    filter_sys_t *p_sys;

    const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma;
    const vlc_chroma_description_t *chroma = vlc_fourcc_GetChromaDescription( fourcc );
    if( !vlc_fourcc_IsYUV( fourcc ) ||
        !chroma || chroma->plane_count != 3 || chroma->pixel_size > 2 )
    {
        msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc );
        return VLC_EGENERIC;
    }

    /* */
    p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sys->chroma = chroma;
    p_sys->i_mode = DEINTERLACE_BLEND;
    p_sys->b_double_rate = false;
    p_sys->b_half_height = true;
    p_sys->b_use_frame_history = false;
    for( int i = 0; i < METADATA_SIZE; i++ )
    {
        p_sys->meta.pi_date[i] = VLC_TS_INVALID;
        p_sys->meta.pi_nb_fields[i] = 2;
        p_sys->meta.pb_top_field_first[i] = true;
    }
    p_sys->i_frame_offset = 0; /* start with default value (first-ever frame
                                  cannot have offset) */
    for( int i = 0; i < HISTORY_SIZE; i++ )
        p_sys->pp_history[i] = NULL;

    IVTCClearState( p_filter );

#if defined(CAN_COMPILE_C_ALTIVEC)
    if( chroma->pixel_size == 1 && vlc_CPU_ALTIVEC() )
        p_sys->pf_merge = MergeAltivec;
    else
#endif
#if defined(CAN_COMPILE_SSE2)
    if( vlc_CPU_SSE2() )
    {
        p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitSSE2 : Merge16BitSSE2;
        p_sys->pf_end_merge = EndMMX;
    }
    else
#endif
#if defined(CAN_COMPILE_MMXEXT)
    if( chroma->pixel_size == 1 && vlc_CPU_MMXEXT() )
    {
        p_sys->pf_merge = MergeMMXEXT;
        p_sys->pf_end_merge = EndMMX;
    }
    else
#endif
#if defined(CAN_COMPILE_3DNOW)
    if( chroma->pixel_size == 1 && vlc_CPU_3dNOW() )
    {
        p_sys->pf_merge = Merge3DNow;
        p_sys->pf_end_merge = End3DNow;
    }
    else
#endif
#if defined(CAN_COMPILE_ARM)
    if( vlc_CPU_ARM_NEON() )
        p_sys->pf_merge =
            (chroma->pixel_size == 1) ? merge8_arm_neon : merge16_arm_neon;
    else
    if( vlc_CPU_ARMv6() )
        p_sys->pf_merge =
            (chroma->pixel_size == 1) ? merge8_armv6 : merge16_armv6;
    else
#endif
    {
        p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric;
#if defined(__i386__) || defined(__x86_64__)
        p_sys->pf_end_merge = NULL;
#endif
    }

    /* */
    config_ChainParse( p_filter, FILTER_CFG_PREFIX, ppsz_filter_options,
                       p_filter->p_cfg );

    char *psz_mode = var_GetNonEmptyString( p_filter, FILTER_CFG_PREFIX "mode" );
    SetFilterMethod( p_filter, psz_mode );
    free( psz_mode );

    if( p_sys->i_mode == DEINTERLACE_PHOSPHOR )
    {
        int i_c420 = var_GetInteger( p_filter,
                                     FILTER_CFG_PREFIX "phosphor-chroma" );
        if( i_c420 != PC_LATEST  &&  i_c420 != PC_ALTLINE  &&
            i_c420 != PC_BLEND   && i_c420 != PC_UPCONVERT )
        {
            msg_Dbg( p_filter, "Phosphor 4:2:0 input chroma mode not set"\
                               "or out of range (valid: 1, 2, 3 or 4), "\
                               "using default" );
            i_c420 = PC_ALTLINE;
        }
        msg_Dbg( p_filter, "using Phosphor 4:2:0 input chroma mode %d",
                           i_c420 );
        /* This maps directly to the phosphor_chroma_t enum. */
        p_sys->phosphor.i_chroma_for_420 = i_c420;

        int i_dimmer = var_GetInteger( p_filter,
                                       FILTER_CFG_PREFIX "phosphor-dimmer" );
        if( i_dimmer < 1  ||  i_dimmer > 4 )
        {
            msg_Dbg( p_filter, "Phosphor dimmer strength not set "\
                               "or out of range (valid: 1, 2, 3 or 4), "\
                               "using default" );
            i_dimmer = 2; /* low */
        }
        msg_Dbg( p_filter, "using Phosphor dimmer strength %d", i_dimmer );
        /* The internal value ranges from 0 to 3. */
        p_sys->phosphor.i_dimmer_strength = i_dimmer - 1;
    }
    else
    {
        p_sys->phosphor.i_chroma_for_420 = PC_ALTLINE;
        p_sys->phosphor.i_dimmer_strength = 1;
    }

    /* */
    video_format_t fmt;
    GetOutputFormat( p_filter, &fmt, &p_filter->fmt_in.video );
    if( !p_filter->b_allow_fmt_out_change &&
        ( fmt.i_chroma != p_filter->fmt_in.video.i_chroma ||
          fmt.i_height != p_filter->fmt_in.video.i_height ) )
    {
        Close( VLC_OBJECT(p_filter) );
        return VLC_EGENERIC;
    }
    p_filter->fmt_out.video = fmt;
    p_filter->fmt_out.i_codec = fmt.i_chroma;
    p_filter->pf_video_filter = Deinterlace;
    p_filter->pf_video_flush  = Flush;
    p_filter->pf_video_mouse  = Mouse;

    msg_Dbg( p_filter, "deinterlacing" );

    return VLC_SUCCESS;
}