diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c index eb773b039a..092befddc7 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.c @@ -117,6 +117,12 @@ gst_vaapi_picture_create (GstVaapiPicture * picture, GST_VAAPI_PICTURE_FLAG_ONEFIELD | GST_VAAPI_PICTURE_FLAG_RFF | GST_VAAPI_PICTURE_FLAG_MVC)); + // Propagate "corrupted" flag while not presuming that the second + // field is itself corrupted if the first one was marked as such + if (GST_VAAPI_PICTURE_IS_CORRUPTED (parent_picture) && + !(args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD)) + GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED); + picture->structure = parent_picture->structure; if ((args->flags & GST_VAAPI_CREATE_PICTURE_FLAG_FIELD) && GST_VAAPI_PICTURE_IS_INTERLACED (picture)) { @@ -348,6 +354,9 @@ do_output (GstVaapiPicture * picture) GST_VIDEO_CODEC_FRAME_FLAG_SET (out_frame, GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + if (GST_VAAPI_PICTURE_IS_CORRUPTED (picture)) + flags |= GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED; + if (GST_VAAPI_PICTURE_IS_MVC (picture)) { if (picture->voc == 0) flags |= GST_VAAPI_SURFACE_PROXY_FLAG_FFB; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h index c9b0dfd48c..c4c4f8586f 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_objects.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_objects.h @@ -68,6 +68,8 @@ typedef enum * @GST_VAAPI_PICTURE_FLAG_ONEFIELD: only one field is valid * @GST_VAAPI_PICTURE_FLAG_MVC: multiview component * @GST_VAAPI_PICTURE_FLAG_RFF: repeat-first-field + * @GST_VAAPI_PICTURE_FLAG_CORRUPTED: picture was reconstructed from + * corrupted references * @GST_VAAPI_PICTURE_FLAG_LAST: first flag that can be used by subclasses * * Enum values used for #GstVaapiPicture flags. @@ -83,7 +85,8 @@ typedef enum GST_VAAPI_PICTURE_FLAG_ONEFIELD = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 6), GST_VAAPI_PICTURE_FLAG_MVC = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 7), GST_VAAPI_PICTURE_FLAG_RFF = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 8), - GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 9), + GST_VAAPI_PICTURE_FLAG_CORRUPTED = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 9), + GST_VAAPI_PICTURE_FLAG_LAST = (GST_VAAPI_CODEC_OBJECT_FLAG_LAST << 10), } GstVaapiPictureFlags; #define GST_VAAPI_PICTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS @@ -126,6 +129,9 @@ typedef enum #define GST_VAAPI_PICTURE_IS_MVC(picture) \ (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_MVC)) +#define GST_VAAPI_PICTURE_IS_CORRUPTED(picture) \ + (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_CORRUPTED)) + /** * GstVaapiPicture: * diff --git a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h index 47d3021352..1dc218c45d 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h +++ b/gst-libs/gst/vaapi/gstvaapisurfaceproxy.h @@ -38,6 +38,8 @@ G_BEGIN_DECLS * @GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD: only one field is available * @GST_VAAPI_SURFACE_PROXY_FLAG_FFB: first frame in bundle, e.g. the first * view component of a MultiView Coded (MVC) frame + * @GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED: the underlying surface is + * corrupted somehow, e.g. reconstructed from invalid references * @GST_VAAPI_SURFACE_PROXY_FLAG_LAST: first flag that can be used by subclasses * * Flags for #GstVaapiDecoderFrame. @@ -49,6 +51,7 @@ typedef enum GST_VAAPI_SURFACE_PROXY_FLAG_RFF = (1 << 2), GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD = (1 << 3), GST_VAAPI_SURFACE_PROXY_FLAG_FFB = (1 << 4), + GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED = (1 << 5), GST_VAAPI_SURFACE_PROXY_FLAG_LAST = (1 << 8) } GstVaapiSurfaceProxyFlags; diff --git a/gst/vaapi/gstvaapidecode.c b/gst/vaapi/gstvaapidecode.c index b40dd97804..93d3a5a61c 100644 --- a/gst/vaapi/gstvaapidecode.c +++ b/gst/vaapi/gstvaapidecode.c @@ -264,7 +264,7 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, GstFlowReturn ret; const GstVaapiRectangle *crop_rect; GstVaapiVideoMeta *meta; - guint flags; + guint flags, out_flags = 0; if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (out_frame)) { proxy = gst_video_codec_frame_get_user_data (out_frame); @@ -282,16 +282,18 @@ gst_vaapidecode_push_decoded_frame (GstVideoDecoder * vdec, gst_vaapi_video_meta_set_surface_proxy (meta, proxy); flags = gst_vaapi_surface_proxy_get_flags (proxy); + if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_CORRUPTED) + out_flags |= GST_BUFFER_FLAG_CORRUPTED; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED) { - guint out_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED; + out_flags |= GST_VIDEO_BUFFER_FLAG_INTERLACED; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF) out_flags |= GST_VIDEO_BUFFER_FLAG_TFF; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF) out_flags |= GST_VIDEO_BUFFER_FLAG_RFF; if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD) out_flags |= GST_VIDEO_BUFFER_FLAG_ONEFIELD; - GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); } + GST_BUFFER_FLAG_SET (out_frame->output_buffer, out_flags); crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy); if (crop_rect) {