vlc | branch: master | Laurent Aimar <[email protected]> | Fri May 25 20:09:26 2012 +0200| [4f93b728e8c007edf9e4af462ac4dc8eb28895ba] | committer: Laurent Aimar
Added partial support for > 8 bits YUV video in the deinterlace filter. Only the basic modes are supported, blend is used as a fallback. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4f93b728e8c007edf9e4af462ac4dc8eb28895ba --- modules/video_filter/deinterlace/deinterlace.c | 26 ++++++------ modules/video_filter/deinterlace/merge.c | 33 ++++++++++++++-- modules/video_filter/deinterlace/merge.h | 50 ++++++++++++++++-------- 3 files changed, 75 insertions(+), 34 deletions(-) diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c index 37062f8..414f87b 100644 --- a/modules/video_filter/deinterlace/deinterlace.c +++ b/modules/video_filter/deinterlace/deinterlace.c @@ -164,35 +164,35 @@ void SetFilterMethod( filter_t *p_filter, const char *psz_method ) p_sys->b_half_height = false; p_sys->b_use_frame_history = false; } - else if( !strcmp( psz_method, "x" ) ) + else if( !strcmp( psz_method, "x" ) && p_sys->chroma->pixel_size == 1 ) { p_sys->i_mode = DEINTERLACE_X; p_sys->b_double_rate = false; p_sys->b_half_height = false; p_sys->b_use_frame_history = false; } - else if( !strcmp( psz_method, "yadif" ) ) + else if( !strcmp( psz_method, "yadif" ) && p_sys->chroma->pixel_size == 1 ) { p_sys->i_mode = DEINTERLACE_YADIF; p_sys->b_double_rate = false; p_sys->b_half_height = false; p_sys->b_use_frame_history = true; } - else if( !strcmp( psz_method, "yadif2x" ) ) + else if( !strcmp( psz_method, "yadif2x" ) && p_sys->chroma->pixel_size == 1 ) { p_sys->i_mode = DEINTERLACE_YADIF2X; p_sys->b_double_rate = true; p_sys->b_half_height = false; p_sys->b_use_frame_history = true; } - else if( !strcmp( psz_method, "phosphor" ) ) + else if( !strcmp( psz_method, "phosphor" ) && p_sys->chroma->pixel_size == 1 ) { p_sys->i_mode = DEINTERLACE_PHOSPHOR; p_sys->b_double_rate = true; p_sys->b_half_height = false; p_sys->b_use_frame_history = true; } - else if( !strcmp( psz_method, "ivtc" ) ) + else if( !strcmp( psz_method, "ivtc" ) && p_sys->chroma->pixel_size == 1 ) { p_sys->i_mode = DEINTERLACE_IVTC; p_sys->b_double_rate = false; @@ -210,7 +210,7 @@ void SetFilterMethod( filter_t *p_filter, const char *psz_method ) { if( strcmp( psz_method, "blend" ) ) msg_Err( p_filter, - "no valid deinterlace mode provided, using \"blend\"" ); + "no valid/compatible deinterlace mode provided, using \"blend\"" ); p_sys->i_mode = DEINTERLACE_BLEND; p_sys->b_double_rate = false; @@ -598,7 +598,7 @@ int Open( vlc_object_t *p_this ) 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 != 1 ) + !chroma || chroma->plane_count != 3 || chroma->pixel_size > 2 ) { msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc ); return VLC_EGENERIC; @@ -628,7 +628,7 @@ int Open( vlc_object_t *p_this ) IVTCClearState( p_filter ); #if defined(CAN_COMPILE_C_ALTIVEC) - if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC ) + if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_ALTIVEC) ) { p_sys->pf_merge = MergeAltivec; p_sys->pf_end_merge = NULL; @@ -636,7 +636,7 @@ int Open( vlc_object_t *p_this ) else #endif #if defined(CAN_COMPILE_SSE) - if( vlc_CPU() & CPU_CAPABILITY_SSE2 ) + if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_SSE2) ) { p_sys->pf_merge = MergeSSE2; p_sys->pf_end_merge = EndMMX; @@ -644,7 +644,7 @@ int Open( vlc_object_t *p_this ) else #endif #if defined(CAN_COMPILE_MMXEXT) - if( vlc_CPU() & CPU_CAPABILITY_MMXEXT ) + if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_MMXEXT) ) { p_sys->pf_merge = MergeMMXEXT; p_sys->pf_end_merge = EndMMX; @@ -652,7 +652,7 @@ int Open( vlc_object_t *p_this ) else #endif #if defined(CAN_COMPILE_3DNOW) - if( vlc_CPU() & CPU_CAPABILITY_3DNOW ) + if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_3DNOW) ) { p_sys->pf_merge = Merge3DNow; p_sys->pf_end_merge = End3DNow; @@ -660,7 +660,7 @@ int Open( vlc_object_t *p_this ) else #endif #if defined __ARM_NEON__ // FIXME: runtime detect support - if( vlc_CPU() & CPU_CAPABILITY_NEON ) + if( chroma->pixel_size == 1 && (vlc_CPU() & CPU_CAPABILITY_NEON) ) { p_sys->pf_merge = MergeNEON; p_sys->pf_end_merge = NULL; @@ -668,7 +668,7 @@ int Open( vlc_object_t *p_this ) else #endif { - p_sys->pf_merge = MergeGeneric; + p_sys->pf_merge = chroma->pixel_size == 1 ? Merge8BitGeneric : Merge16BitGeneric; p_sys->pf_end_merge = NULL; } diff --git a/modules/video_filter/deinterlace/merge.c b/modules/video_filter/deinterlace/merge.c index 0a037b0..b3e6e59 100644 --- a/modules/video_filter/deinterlace/merge.c +++ b/modules/video_filter/deinterlace/merge.c @@ -45,8 +45,8 @@ * Merge (line blending) routines *****************************************************************************/ -void MergeGeneric( void *_p_dest, const void *_p_s1, - const void *_p_s2, size_t i_bytes ) +void Merge8BitGeneric( void *_p_dest, const void *_p_s1, + const void *_p_s2, size_t i_bytes ) { uint8_t* p_dest = (uint8_t*)_p_dest; const uint8_t *p_s1 = (const uint8_t *)_p_s1; @@ -73,6 +73,31 @@ void MergeGeneric( void *_p_dest, const void *_p_s1, } } +void Merge16BitGeneric( void *_p_dest, const void *_p_s1, + const void *_p_s2, size_t i_bytes ) +{ + uint16_t* p_dest = (uint16_t*)_p_dest; + const uint16_t *p_s1 = (const uint16_t *)_p_s1; + const uint16_t *p_s2 = (const uint16_t *)_p_s2; + uint16_t* p_end = p_dest + (i_bytes/2) - 4; + + while( p_dest < p_end ) + { + *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1; + *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1; + *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1; + *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1; + } + + p_end += 4; + + while( p_dest < p_end ) + { + *p_dest++ = ( (uint32_t)(*p_s1++) + (uint32_t)(*p_s2++) ) >> 1; + } + +} + #if defined(CAN_COMPILE_MMXEXT) void MergeMMXEXT( void *_p_dest, const void *_p_s1, const void *_p_s2, size_t i_bytes ) @@ -246,7 +271,7 @@ void MergeNEON (void *restrict out, const void *in1, if (mis) { - MergeGeneric (outp, in1p, in2p, mis); + Merge8BitGeneric (outp, in1p, in2p, mis); outp += mis; in1p += mis; in2p += mis; @@ -291,7 +316,7 @@ void MergeNEON (void *restrict out, const void *in1, "q8", "q9", "q10", "q11", "memory"); n &= 15; if (n) - MergeGeneric (outp, in1p, in2p, n); + Merge8BitGeneric (outp, in1p, in2p, n); } #endif diff --git a/modules/video_filter/deinterlace/merge.h b/modules/video_filter/deinterlace/merge.h index 999d842..7f4af07 100644 --- a/modules/video_filter/deinterlace/merge.h +++ b/modules/video_filter/deinterlace/merge.h @@ -41,18 +41,7 @@ Note that you'll need to include vlc_filter.h and deinterlace.h to use these. -*/ -#define Merge p_filter->p_sys->pf_merge -#define EndMerge if(p_filter->p_sys->pf_end_merge) p_filter->p_sys->pf_end_merge -/***************************************************************************** - * Merge routines - *****************************************************************************/ - -/** - * Generic routine to blend pixels from two picture lines. - * No inline assembler acceleration. - * * Note that the Open() call of the deinterlace filter automatically selects * the most appropriate merge routine based on the CPU capabilities. * You can call the most appropriate version automatically, from a function @@ -65,20 +54,47 @@ * Macro syntax: * Merge( _p_dest, _p_s1, _p_s2, i_bytes ); * - * See also the EndMerge() macro, which must be called after the merge is - * finished, if the Merge() macro was used to perform the merge. - * - * i_bytes > 0; no other restrictions. This holds for all versions of the + * i_bytes > 0; no other restrictions. This holds for all versions of the * merge routine. * + */ +#define Merge p_filter->p_sys->pf_merge + +/* + * EndMerge() macro, which must be called after the merge is + * finished, if the Merge() macro was used to perform the merge. + */ +#define EndMerge if(p_filter->p_sys->pf_end_merge) p_filter->p_sys->pf_end_merge + +/***************************************************************************** + * Merge routines + *****************************************************************************/ + +/** + * Generic routine to blend 8 bit pixels from two picture lines. + * No inline assembler acceleration. + * * @param _p_dest Target line. Blend result = (A + B)/2. * @param _p_s1 Source line A. * @param _p_s2 Source line B. * @param i_bytes Number of bytes to merge. * @see Open() */ -void MergeGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2, - size_t i_bytes ); +void Merge8BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2, + size_t i_bytes ); + +/** + * Generic routine to blend 16 bit pixels from two picture lines. + * No inline assembler acceleration. + * + * @param _p_dest Target line. Blend result = (A + B)/2. + * @param _p_s1 Source line A. + * @param _p_s2 Source line B. + * @param i_bytes Number of *bytes* to merge. + * @see Open() + */ +void Merge16BitGeneric( void *_p_dest, const void *_p_s1, const void *_p_s2, + size_t i_bytes ); #if defined(CAN_COMPILE_C_ALTIVEC) /** _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
