diff options
author | He Junyan <junyan.he@intel.com> | 2020-11-16 23:53:39 +0800 |
---|---|---|
committer | He Junyan <junyan.he@intel.com> | 2020-11-17 01:21:45 +0800 |
commit | 672a30d0def1f02b6911892ddd4dfc854e1727d3 (patch) | |
tree | 72268e4c87c313201c4d25644e3be0dcf187c7c2 /sys | |
parent | d3d2af6c84446cffcd041f76baa8781b1a560eca (diff) | |
download | gstreamer-plugins-bad-672a30d0def1f02b6911892ddd4dfc854e1727d3.tar.gz |
va: basedec: fallback to system memory if downstream caps is any.
When the downstream element reports an ANY caps, and it also fails to
support VideoMeta, we should fallback to the system memory.
Note: the basetransform kind elements never return valid allocation
query before set_caps(). So, if a basetransform return an ANY sink
caps, we always fallback to system memory for it.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1711>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/va/gstvabasedec.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/sys/va/gstvabasedec.c b/sys/va/gstvabasedec.c index b33e85432..3e9dcbdea 100644 --- a/sys/va/gstvabasedec.c +++ b/sys/va/gstvabasedec.c @@ -438,6 +438,22 @@ _default_video_format_from_chroma (guint chroma_type) } } +/* Check whether the downstream supports VideoMeta; if not, we need to + * fallback to the system memory. */ +static gboolean +_downstream_has_video_meta (GstVaBaseDec * base, GstCaps * caps) +{ + GstQuery *query; + gboolean ret = FALSE; + + query = gst_query_new_allocation (caps, FALSE); + if (gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (base), query)) + ret = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + gst_query_unref (query); + + return ret; +} + void gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base, GstVideoFormat * format, GstCapsFeatures ** capsfeatures) @@ -447,9 +463,18 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base, GstStructure *structure; const GValue *v_format; guint num_structures, i; + gboolean is_any; g_return_if_fail (base); + /* verify if peer caps is any */ + { + peer_caps = + gst_pad_peer_query_caps (GST_VIDEO_DECODER_SRC_PAD (base), NULL); + is_any = gst_caps_is_any (peer_caps); + gst_clear_caps (&peer_caps); + } + peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (base)); GST_DEBUG_OBJECT (base, "Allowed caps %" GST_PTR_FORMAT, peer_caps); @@ -475,19 +500,32 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base, else gst_clear_caps (&peer_caps); - if (gst_caps_is_empty (preferred_caps) - || gst_caps_is_any (preferred_caps)) { - /* if any or not linked yet then system memory and nv12 */ + if (gst_caps_is_empty (preferred_caps)) { if (capsfeatures) - *capsfeatures = NULL; + *capsfeatures = NULL; /* system memory */ if (format) *format = _default_video_format_from_chroma (base->rt_format); goto bail; } - features = gst_caps_get_features (preferred_caps, 0); - if (features && capsfeatures) - *capsfeatures = gst_caps_features_copy (features); + if (capsfeatures) { + features = gst_caps_get_features (preferred_caps, 0); + if (features) { + *capsfeatures = gst_caps_features_copy (features); + + if (is_any + && !gst_caps_features_is_equal (features, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) + && !_downstream_has_video_meta (base, preferred_caps)) { + GST_INFO_OBJECT (base, "Downstream reports ANY caps but without" + " VideoMeta support; fallback to system memory."); + gst_caps_features_free (*capsfeatures); + *capsfeatures = NULL; + } + } else { + *capsfeatures = NULL; + } + } if (!format) goto bail; |