/** * 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; }
/***************************************************************************** * 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; }
/***************************************************************************** * 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; }
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; }