@ -948,7 +948,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
*/
static void vc1_mc_4mv_chroma4 ( VC1Context * v )
static void vc1_mc_4mv_chroma4 ( VC1Context * v , int dir , int dir2 , int avg )
{
MpegEncContext * s = & v - > s ;
H264ChromaContext * h264chroma = & v - > h264chroma ;
@ -960,17 +960,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
static const int s_rndtblfield [ 16 ] = { 0 , 0 , 1 , 2 , 4 , 4 , 5 , 6 , 2 , 2 , 3 , 8 , 6 , 6 , 7 , 12 } ;
int v_dist = fieldmv ? 1 : 4 ; // vertical offset for lower sub-blocks
int v_edge_pos = s - > v_edge_pos > > 1 ;
int use_ic = v - > last_use_ic ;
int use_ic ;
uint8_t ( * lutuv ) [ 256 ] ;
if ( ! v - > s . last_picture . f . data [ 0 ] )
return ;
if ( s - > flags & CODEC_FLAG_GRAY )
return ;
for ( i = 0 ; i < 4 ; i + + ) {
tx = s - > mv [ 0 ] [ i ] [ 0 ] ;
int d = i < 2 ? dir : dir2 ;
tx = s - > mv [ d ] [ i ] [ 0 ] ;
uvmx_field [ i ] = ( tx + ( ( tx & 3 ) = = 3 ) ) > > 1 ;
ty = s - > mv [ 0 ] [ i ] [ 1 ] ;
ty = s - > mv [ d ] [ i ] [ 1 ] ;
if ( fieldmv )
uvmy_field [ i ] = ( ty > > 4 ) * 8 + s_rndtblfield [ ty & 0xF ] ;
else
@ -984,8 +984,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
// FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
uvsrc_x = av_clip ( uvsrc_x , - 8 , s - > avctx - > coded_width > > 1 ) ;
uvsrc_y = av_clip ( uvsrc_y , - 8 , s - > avctx - > coded_height > > 1 ) ;
if ( i < 2 ? dir : dir2 ) {
srcU = s - > next_picture . f . data [ 1 ] + uvsrc_y * s - > uvlinesize + uvsrc_x ;
srcV = s - > next_picture . f . data [ 2 ] + uvsrc_y * s - > uvlinesize + uvsrc_x ;
lutuv = v - > next_lutuv ;
use_ic = v - > next_use_ic ;
} else {
srcU = s - > last_picture . f . data [ 1 ] + uvsrc_y * s - > uvlinesize + uvsrc_x ;
srcV = s - > last_picture . f . data [ 2 ] + uvsrc_y * s - > uvlinesize + uvsrc_x ;
lutuv = v - > last_lutuv ;
use_ic = v - > last_use_ic ;
}
uvmx_field [ i ] = ( uvmx_field [ i ] & 3 ) < < 1 ;
uvmy_field [ i ] = ( uvmy_field [ i ] & 3 ) < < 1 ;
@ -1010,20 +1019,29 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
if ( use_ic ) {
int i , j ;
uint8_t * src , * src2 ;
const uint8_t * lutuv = v - > last_lutuv [ v - > ref_field_type [ 0 ] ] ;
src = srcU ;
src2 = srcV ;
for ( j = 0 ; j < 5 ; j + + ) {
int f = ( uvsrc_y + ( j < < fieldmv ) ) & 1 ;
for ( i = 0 ; i < 5 ; i + + ) {
src [ i ] = lutuv [ src [ i ] ] ;
src2 [ i ] = lutuv [ src2 [ i ] ] ;
src [ i ] = lutuv [ f ] [ src [ i ] ] ;
src2 [ i ] = lutuv [ f ] [ src2 [ i ] ] ;
}
src + = s - > uvlinesize < < 1 ;
src2 + = s - > uvlinesize < < 1 ;
}
}
}
if ( avg ) {
if ( ! v - > rnd ) {
h264chroma - > avg_h264_chroma_pixels_tab [ 1 ] ( s - > dest [ 1 ] + off , srcU , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
h264chroma - > avg_h264_chroma_pixels_tab [ 1 ] ( s - > dest [ 2 ] + off , srcV , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
} else {
v - > vc1dsp . avg_no_rnd_vc1_chroma_pixels_tab [ 1 ] ( s - > dest [ 1 ] + off , srcU , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
v - > vc1dsp . avg_no_rnd_vc1_chroma_pixels_tab [ 1 ] ( s - > dest [ 2 ] + off , srcV , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
}
} else {
if ( ! v - > rnd ) {
h264chroma - > put_h264_chroma_pixels_tab [ 1 ] ( s - > dest [ 1 ] + off , srcU , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
h264chroma - > put_h264_chroma_pixels_tab [ 1 ] ( s - > dest [ 2 ] + off , srcV , s - > uvlinesize < < fieldmv , 4 , uvmx_field [ i ] , uvmy_field [ i ] ) ;
@ -1033,6 +1051,7 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
}
}
}
}
/***********************************************************************/
/**
@ -3845,7 +3864,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
vc1_pred_mv_intfr ( v , i , dmv_x , dmv_y , 0 , v - > range_x , v - > range_y , v - > mb_type [ 0 ] , 0 ) ;
vc1_mc_4mv_luma ( v , i , 0 , 0 ) ;
} else if ( i = = 4 ) {
vc1_mc_4mv_chroma4 ( v ) ;
vc1_mc_4mv_chroma4 ( v , 0 , 0 , 0 ) ;
}
}
} else if ( twomv ) {
@ -3864,7 +3883,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
vc1_pred_mv_intfr ( v , 2 , dmv_x , dmv_y , 2 , v - > range_x , v - > range_y , v - > mb_type [ 0 ] , 0 ) ;
vc1_mc_4mv_luma ( v , 2 , 0 , 0 ) ;
vc1_mc_4mv_luma ( v , 3 , 0 , 0 ) ;
vc1_mc_4mv_chroma4 ( v ) ;
vc1_mc_4mv_chroma4 ( v , 0 , 0 , 0 ) ;
} else {
mvbp = ff_vc1_mbmode_intfrp [ v - > fourmvswitch ] [ idx_mbmode ] [ 2 ] ;
dmv_x = dmv_y = 0 ;
@ -4512,7 +4531,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
vc1_mc_4mv_luma ( v , i , 0 , 0 ) ;
vc1_mc_4mv_luma ( v , i , 1 , 1 ) ;
}
vc1_mc_4mv_chroma4 ( v ) ;
vc1_mc_4mv_chroma4 ( v , 0 , 0 , 0 ) ;
vc1_mc_4mv_chroma4 ( v , 1 , 1 , 1 ) ;
} else {
vc1_mc_1mv ( v , 0 ) ;
vc1_interp_mc ( v ) ;
@ -4531,7 +4551,8 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
vc1_mc_4mv_luma ( v , j + 1 , dir , dir ) ;
}
vc1_mc_4mv_chroma4 ( v ) ;
vc1_mc_4mv_chroma4 ( v , 0 , 0 , 0 ) ;
vc1_mc_4mv_chroma4 ( v , 1 , 1 , 1 ) ;
} else if ( bmvtype = = BMV_TYPE_INTERPOLATED ) {
mvbp = v - > twomvbp ;
dmv_x = dmv_y = 0 ;
@ -4579,7 +4600,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
vc1_mc_4mv_luma ( v , 1 , dir , 0 ) ;
vc1_mc_4mv_luma ( v , 2 , dir2 , 0 ) ;
vc1_mc_4mv_luma ( v , 3 , dir2 , 0 ) ;
vc1_mc_4mv_chroma4 ( v ) ;
vc1_mc_4mv_chroma4 ( v , dir , dir2 , 0 ) ;
} else {
dir = bmvtype = = BMV_TYPE_BACKWARD ;