GNOME Bugzilla – Bug 797142
caps: Using gst_caps_fixate() on src pad leads to lies in the caps
Last modified: 2018-11-03 12:48:08 UTC
The default implementation of fixate in basesrc is based on gst_caps_fixate(). This though can lead to terribly lies in the resulting caps if downstream element uses ranges or set to explicitly state what is supported. As in: udpsrc caps="video/x-h264" ! h264parse ! avdec_h264 ! fakesink avdec_h264 sets the alignment to { au, nal }, in order to ensure that it's one of these two alignment that are provided. udpsrc, which uses BaseSrc default, will happily pretend to produce: video/x-h264, alignment=(string)au, stream-format=(string)avc This is highly problematic, since we now lie to h264parse, triggering optimization that should not. The downstream solution to that is to remove the alignment and to write code in When we receive that caps that check that alignment is present. That's not a great solution because it requires coding the requirements and also it reduce the quality of the documentation. While I'm under the impression this may break some valid use cases, I'd like to start experimenting a solution that would make our caps negotiation more strict. My first proposal would be to create a new version of gst_caps_fixate(), let's say gst_caps_fixate_known (caps, known_field), or gst_caps_fixate_from_template (caps, template). The idea is that the opration would first remove all the unkmown field before fixating. As a side effect, in the previous example, udpsrc would negotiate just "
... would negotiate just "video/x-h264". Now, we could certainly try and fix it for udpsrc, but same issue happens if you use filesrc, or other sources that advertise ANY.
This is not only a problem with fixate(). intersect() will produce the same caps (and you would get e.g. the same problem if you put a capsfilter between source and decoder), and is_subset() considers them compatible. The real problem here is that the source is not providing complete caps, or more general that we don't have a way to declare mandatory and optional fields in the caps.
(In reply to Sebastian Dröge (slomo) from comment #2) > The real problem here is that the source is not providing complete caps, or > more general that we don't have a way to declare mandatory and optional > fields in the caps. That I believe is the design error, which I cannot fix. But I can improve things. If sources drops the field that aren't supported, you'll get only the media type when negotiating with ANY. The source would drop the field at fixating time. Just the media type should make is_subset() fail.
I think we may be able to do something by filtering the fields in the reply to the caps query to only those that the source's template (or maybe the filter or maybe a superset of those) knows about. Maybe making this optional based on a flag on the pad. I have yet to do any real experimentation.
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/311.