Commit e3e5395d authored by Laurent Aimar's avatar Laurent Aimar

Added support for all planar 8 bit YUV chromas to the deinterlace filter.

parent 87371c40
......@@ -1438,9 +1438,9 @@ static bool IVTCOutputOrDropFrame( filter_t *p_filter, picture_t *p_dst )
else if( op == IVTC_OP_COPY_C )
picture_Copy( p_dst, p_curr );
else if( op == IVTC_OP_COMPOSE_TNBC )
ComposeFrame( p_filter, p_dst, p_next, p_curr, CC_ALTLINE );
ComposeFrame( p_filter, p_dst, p_next, p_curr, CC_ALTLINE, false );
else if( op == IVTC_OP_COMPOSE_TCBN )
ComposeFrame( p_filter, p_dst, p_curr, p_next, CC_ALTLINE );
ComposeFrame( p_filter, p_dst, p_curr, p_next, CC_ALTLINE, false );
/* Slide history of outgoing interlace scores. This must be done last,
and only if the frame was not dropped, so we do it here.
......
......@@ -68,8 +68,9 @@
* @see RenderPhosphor()
* @see ComposeFrame()
*/
static void DarkenField( picture_t *p_dst, const int i_field,
const int i_strength )
static void DarkenField( picture_t *p_dst,
const int i_field, const int i_strength,
bool process_chroma )
{
assert( p_dst != NULL );
assert( i_field == 0 || i_field == 1 );
......@@ -147,8 +148,7 @@ static void DarkenField( picture_t *p_dst, const int i_field,
The chroma processing is a bit more complicated than luma,
and needs MMX for vectorization.
*/
if( p_dst->format.i_chroma == VLC_CODEC_I422 ||
p_dst->format.i_chroma == VLC_CODEC_J422 )
if( process_chroma )
{
for( i_plane = 0 ; i_plane < p_dst->i_planes ; i_plane++ )
{
......@@ -213,7 +213,7 @@ static void DarkenField( picture_t *p_dst, const int i_field,
(*po) = 128 + ( ((*po) - 128) / (1 << i_strength) );
} /* for p_out... */
} /* for i_plane... */
} /* if b_i422 */
} /* if process_chroma */
#ifdef CAN_COMPILE_MMXEXT
if( u_cpu & CPU_CAPABILITY_MMXEXT )
......@@ -265,9 +265,13 @@ int RenderPhosphor( filter_t *p_filter,
p_in_top = p_old;
}
compose_chroma_t cc = CC_ALTLINE; /* initialize to prevent compiler warning */
switch( p_sys->phosphor.i_chroma_for_420 )
compose_chroma_t cc = CC_ALTLINE;
if( 2 * p_sys->chroma->p[1].h.num == p_sys->chroma->p[1].h.den &&
2 * p_sys->chroma->p[2].h.num == p_sys->chroma->p[2].h.den )
{
/* Only 420 like chroma */
switch( p_sys->phosphor.i_chroma_for_420 )
{
case PC_BLEND:
cc = CC_MERGE;
break;
......@@ -287,9 +291,9 @@ int RenderPhosphor( filter_t *p_filter,
/* The above are the only possibilities, if there are no bugs. */
assert(0);
break;
}
}
ComposeFrame( p_filter, p_dst, p_in_top, p_in_bottom, cc );
ComposeFrame( p_filter, p_dst, p_in_top, p_in_bottom, cc, p_filter->fmt_in.video.i_chroma == VLC_CODEC_YV12 );
/* Simulate phosphor light output decay for the old field.
......@@ -301,7 +305,9 @@ int RenderPhosphor( filter_t *p_filter,
In most use cases the dimmer is used.
*/
if( p_sys->phosphor.i_dimmer_strength > 0 )
DarkenField( p_dst, !i_field, p_sys->phosphor.i_dimmer_strength );
DarkenField( p_dst, !i_field, p_sys->phosphor.i_dimmer_strength,
p_sys->chroma->p[1].h.num == p_sys->chroma->p[1].h.den &&
p_sys->chroma->p[2].h.num == p_sys->chroma->p[2].h.den );
return VLC_SUCCESS;
}
......@@ -242,7 +242,8 @@ void GetOutputFormat( filter_t *p_filter,
}
if( p_sys->i_mode == DEINTERLACE_PHOSPHOR &&
p_src->i_chroma != VLC_CODEC_I422 && p_src->i_chroma != VLC_CODEC_J422 &&
2 * p_sys->chroma->p[1].h.num == p_sys->chroma->p[1].h.den &&
2 * p_sys->chroma->p[2].h.num == p_sys->chroma->p[2].h.den &&
p_sys->phosphor.i_chroma_for_420 == PC_UPCONVERT )
{
p_dst->i_chroma = p_src->i_chroma == VLC_CODEC_J420 ? VLC_CODEC_J422 :
......@@ -255,19 +256,6 @@ void GetOutputFormat( filter_t *p_filter,
}
/*****************************************************************************
* IsChromaSupported: return whether the specified chroma is implemented.
*****************************************************************************/
bool IsChromaSupported( vlc_fourcc_t i_chroma )
{
return i_chroma == VLC_CODEC_I420 ||
i_chroma == VLC_CODEC_J420 ||
i_chroma == VLC_CODEC_YV12 ||
i_chroma == VLC_CODEC_I422 ||
i_chroma == VLC_CODEC_J422;
}
/*****************************************************************************
* video filter2 functions
*****************************************************************************/
......@@ -607,14 +595,21 @@ int Open( vlc_object_t *p_this )
filter_t *p_filter = (filter_t*)p_this;
filter_sys_t *p_sys;
if( !IsChromaSupported( p_filter->fmt_in.video.i_chroma ) )
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 )
{
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;
......
......@@ -89,6 +89,8 @@ typedef struct {
*/
struct filter_sys_t
{
const vlc_chroma_description_t *chroma;
int i_mode; /**< Deinterlace mode */
/* Algorithm behaviour flags */
......@@ -150,20 +152,6 @@ void GetOutputFormat( filter_t *p_filter,
video_format_t *p_dst,
const video_format_t *p_src );
/**
* Returns whether the specified chroma is implemented in the deinterlace
* filter.
*
* Currently, supported chromas are I420, J420 (4:2:0 full scale),
* YV12 (like I420, but YVU), I422 and J422.
*
* Note for deinterlace hackers: adding support for a new chroma typically
* requires changes to all low-level functions across all the algorithms.
*
* @see vlc_fourcc_t
*/
bool IsChromaSupported( vlc_fourcc_t i_chroma );
/*****************************************************************************
* video filter2 functions
*****************************************************************************/
......
......@@ -246,11 +246,11 @@ static inline int TestForMotionInBlock( uint8_t *p_pix_p, uint8_t *p_pix_c,
*****************************************************************************/
/* See header for function doc. */
void ComposeFrame( filter_t *p_filter, picture_t *p_outpic,
void ComposeFrame( filter_t *p_filter,
picture_t *p_outpic,
picture_t *p_inpic_top, picture_t *p_inpic_bottom,
compose_chroma_t i_output_chroma )
compose_chroma_t i_output_chroma, bool swapped_uv_conversion )
{
assert( p_filter != NULL );
assert( p_outpic != NULL );
assert( p_inpic_top != NULL );
assert( p_inpic_bottom != NULL );
......@@ -262,21 +262,14 @@ void ComposeFrame( filter_t *p_filter, picture_t *p_outpic,
i_output_chroma == CC_SOURCE_BOTTOM ||
i_output_chroma == CC_MERGE );
const int i_chroma = p_filter->fmt_in.video.i_chroma;
const bool b_i422 = i_chroma == VLC_CODEC_I422 ||
i_chroma == VLC_CODEC_J422;
const bool b_upconvert_chroma = ( !b_i422 &&
i_output_chroma == CC_UPCONVERT );
const bool b_upconvert_chroma = i_output_chroma == CC_UPCONVERT;
for( int i_plane = 0 ; i_plane < p_inpic_top->i_planes ; i_plane++ )
{
bool b_is_chroma_plane = ( i_plane == U_PLANE || i_plane == V_PLANE );
/* YV12 is YVU, but I422 is YUV. For such input, swap chroma planes
in output when converting to 4:2:2. */
int i_out_plane;
if( b_is_chroma_plane && b_upconvert_chroma &&
i_chroma == VLC_CODEC_YV12 )
if( b_is_chroma_plane && b_upconvert_chroma && swapped_uv_conversion )
{
if( i_plane == U_PLANE )
i_out_plane = V_PLANE;
......@@ -289,7 +282,7 @@ void ComposeFrame( filter_t *p_filter, picture_t *p_outpic,
}
/* Copy luma or chroma, alternating between input fields. */
if( !b_is_chroma_plane || b_i422 || i_output_chroma == CC_ALTLINE )
if( !b_is_chroma_plane || i_output_chroma == CC_ALTLINE )
{
/* Do an alternating line copy. This is always done for luma,
and for 4:2:2 chroma. It can be requested for 4:2:0 chroma
......
......@@ -89,13 +89,15 @@ typedef enum { CC_ALTLINE, CC_UPCONVERT, CC_SOURCE_TOP, CC_SOURCE_BOTTOM,
* @param p_inpic_top Picture to extract the top field from.
* @param p_inpic_bottom Picture to extract the bottom field from.
* @param i_output_chroma Chroma operation mode for 4:2:0 (see function doc)
* @param swapped_uv_conversion Swap UV while up converting (for YV12)
* @see compose_chroma_t
* @see RenderPhosphor()
* @see RenderIVTC()
*/
void ComposeFrame( filter_t *p_filter, picture_t *p_outpic,
void ComposeFrame( filter_t *p_filter,
picture_t *p_outpic,
picture_t *p_inpic_top, picture_t *p_inpic_bottom,
compose_chroma_t i_output_chroma );
compose_chroma_t i_output_chroma, bool swapped_uv_conversion );
/**
* Helper function: Estimates the number of 8x8 blocks which have motion
......
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