Commit 4f93b728 authored by Laurent Aimar's avatar 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.
parent e3e5395d
......@@ -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;
}
......
......@@ -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
......
......@@ -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)
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment