[FFmpeg-devel] [PATCH] avcodec/vc1_pred: properly clip interlaced motion vectors
Jerome Borsboom
jerome.borsboom at carpalis.nl
Sat Apr 21 22:05:28 EEST 2018
> Fixes #2557.
>
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> libavcodec/vc1_pred.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c
> index 54712f6b7a..9f42a930fe 100644
> --- a/libavcodec/vc1_pred.c
> +++ b/libavcodec/vc1_pred.c
> @@ -98,9 +98,9 @@ static av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */,
> }
>
> if (v->cur_field_type && !v->ref_field_type[dir])
> - return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
> + return av_clip(scaledvalue, -v->range_y / 2 - 1, v->range_y / 2);
> else
> - return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
> + return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 + 1);
> }
>
> static av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
> --
> 2.11.0
scaleforsame_y references ref_field_type. Therefore, it needs to be set
before scaleforsame is called.
Signed-off-by: Jerome Borsboom <jerome.borsboom at carpalis.nl>
---
I am not sure your patch is correct. The existing implementation agrees with VC-1 spec.
See Figure 119 in 10.3.5.4.3.4.2 in particular. Please have a look if the patch below solves
the issue. ref_field_type is referenced in scaleforsame_y and needs to be set earlier in
ff_vc1_pred_mv to have the desired effect.
libavcodec/vc1_pred.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c
index 54712f6b7a..3a52a22bc6 100644
--- a/libavcodec/vc1_pred.c
+++ b/libavcodec/vc1_pred.c
@@ -341,6 +341,8 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
} else
opposite = 0;
if (opposite) {
+ v->mv_f[dir][xy + v->blocks_off] = 1;
+ v->ref_field_type[dir] = !v->cur_field_type;
if (a_valid && !a_f) {
field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
@@ -353,9 +355,9 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
}
- v->mv_f[dir][xy + v->blocks_off] = 1;
- v->ref_field_type[dir] = !v->cur_field_type;
} else {
+ v->mv_f[dir][xy + v->blocks_off] = 0;
+ v->ref_field_type[dir] = v->cur_field_type;
if (a_valid && a_f) {
field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
@@ -368,8 +370,6 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
}
- v->mv_f[dir][xy + v->blocks_off] = 0;
- v->ref_field_type[dir] = v->cur_field_type;
}
if (a_valid) {
--
2.13.6
More information about the ffmpeg-devel
mailing list