From f196605fc81ca928e446876d4e5ec93881f430cf Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 14 Nov 2012 10:27:12 +0100 Subject: [PATCH] h264: fix interlaced stream decoding with MMCO. Fix decoding of interlaced streams when adaptive_ref_pic_marking_mode_flag is equal to 1, i.e. when memory management control operations are used. In particular, when field_pic_flag is set to 0, the new reference flags shall be applied to both fields. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 32 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index ed812ad..f9998a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -185,13 +185,19 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder) static inline void gst_vaapi_picture_h264_set_reference( GstVaapiPictureH264 *picture, - guint reference_flags + guint reference_flags, + gboolean other_field ) { g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture)); GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); + + if (!other_field || !(picture = picture->other_field)) + return; + GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE); + GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags); } static inline GstVaapiPictureH264 * @@ -2200,13 +2206,12 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder) } ref_picture = priv->short_ref[m]; - gst_vaapi_picture_h264_set_reference(ref_picture, 0); + gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE); ARRAY_REMOVE_INDEX(priv->short_ref, m); - /* Both fields need to be marked as "unused for reference" */ - if (ref_picture->other_field) - gst_vaapi_picture_h264_set_reference(ref_picture->other_field, 0); - if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) { + /* Both fields need to be marked as "unused for reference", so + remove the other field from the short_ref[] list as well */ + if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) { for (i = 0; i < priv->short_ref_count; i++) { if (priv->short_ref[i] == ref_picture->other_field) { ARRAY_REMOVE_INDEX(priv->short_ref, i); @@ -2246,7 +2251,8 @@ exec_ref_pic_marking_adaptive_mmco_1( if (i < 0) return; - gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(priv->short_ref, i); } @@ -2265,7 +2271,8 @@ exec_ref_pic_marking_adaptive_mmco_2( if (i < 0) return; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, + GST_VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(priv->long_ref, i); } @@ -2286,7 +2293,7 @@ exec_ref_pic_marking_adaptive_mmco_3( break; } if (i != priv->long_ref_count) { - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE); ARRAY_REMOVE_INDEX(priv->long_ref, i); } @@ -2301,7 +2308,8 @@ exec_ref_pic_marking_adaptive_mmco_3( ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(ref_picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, + GST_VAAPI_PICTURE_IS_FRAME(picture)); } /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx @@ -2321,7 +2329,7 @@ exec_ref_pic_marking_adaptive_mmco_4( for (i = 0; i < priv->long_ref_count; i++) { if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx) continue; - gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0); + gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE); ARRAY_REMOVE_INDEX(priv->long_ref, i); i--; } @@ -2364,7 +2372,7 @@ exec_ref_pic_marking_adaptive_mmco_6( { picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx; gst_vaapi_picture_h264_set_reference(picture, - GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); + GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE); } /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */ -- 2.7.4