GNOME Bugzilla – Bug 797332
basesrc: Allow for suppressing the initial negotiation
Last modified: 2018-11-03 12:49:00 UTC
Run this example: gst-launch-1.0 audiotestsrc ! "audio/x-raw,rate=44100" ! interaudiosink interaudiosrc ! fakesink sync=true silent=false -v We'd expect this to negotiate the downstream caps to 44100 Hz. This is also what happens - but initially, the caps are set to 48000 Hz instead. Here's the output: /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event ******* (fakesink0:sink) E (type: stream-start (10254), GstEventStreamStart, stream-id=(string)ea61450f33201961286324e03482a1c5, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)2;) 0x7f0e5c004c20 /GstPipeline:pipeline0/GstInterAudioSrc:interaudiosrc0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, rate=(int)48000, channels=(int)2, layout=(string)interleaved /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event ******* (fakesink0:sink) E (type: caps (12814), GstEventCaps, caps=(GstCaps)"audio/x-raw\,\ format\=\(string\)S16LE\,\ rate\=\(int\)48000\,\ channels\=\(int\)2\,\ layout\=\(string\)interleaved";) 0x7f0e5c004c90 /GstPipeline:pipeline0/GstAudioTestSrc:audiotestsrc0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 /GstPipeline:pipeline0/GstInterAudioSink:interaudiosink0.GstPad:sink: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 Setting pipeline to PLAYING ... New clock: GstSystemClock /GstPipeline:pipeline0/GstInterAudioSrc:interaudiosrc0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event ******* (fakesink0:sink) E (type: caps (12814), GstEventCaps, caps=(GstCaps)"audio/x-raw\,\ format\=\(string\)S16LE\,\ layout\=\(string\)interleaved\,\ rate\=\(int\)44100\,\ channels\=\(int\)1";) 0x7f0e5c004d00 /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)44100, channels=(int)1 /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event ******* (fakesink0:sink) E (type: segment (17934), GstEventSegment, segment=(GstSegment)"GstSegment, flags=(GstSegmentFlags)GST_SEGMENT_FLAG_NONE, rate=(double)1, applied-rate=(double)1, format=(GstFormat)GST_FORMAT_TIME, base=(guint64)0, offset=(guint64)0, start=(guint64)0, stop=(guint64)18446744073709551615, time=(guint64)0, position=(guint64)0, duration=(guint64)18446744073709551615;";) 0x7f0e5c004de0 /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = preroll ******* /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain ******* (fakesink0:sink) (2400 bytes, dts: none, pts: 0:00:00.000470130, duration: 0:00:00.027210884, offset: 0, offset_end: 1200, flags: 00004840 discont gap tag-memory , meta: none) 0x7f0e540086b0 /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain ******* (fakesink0:sink) (2204 bytes, dts: none, pts: 0:00:00.027681014, duration: 0:00:00.024988662, offset: 1200, offset_end: 2302, flags: 00000000 , meta: none) 0x7f0e540087c0 /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = chain ******* (fakesink0:sink) (2204 bytes, dts: none, pts: 0:00:00.052669676, duration: 0:00:00.024988662, offset: 2302, offset_end: 3404, flags: 00000000 , meta: none) 0x7f0e540088d0 The reason for these initial 48000 Hz is that right at the beginning, basesrc tries to come up with fixated src caps. However, at that point, interaudiosrc does not have the actual caps yet (that is, the caps for the data that comes from interaudiosink). So, instead, interaudiosrc's fixate() function is called to fixate the template caps. The interaudiosrc.c fixate function contains this line: gst_structure_fixate_field_nearest_int (structure, "rate", 48000); This is not a bug in interaudiosrc. Rather, the basesrc class tries to output a caps event too early. It would be better if it were possible to inform basesrc that the srccaps will be known later, and that until then, it should not try to push a caps event downstream. It would be good to add functions to the API for this purpose.
That seems useful indeed. Some flag to delay caps negotiation until the first buffer is available from the subclass, i.e. create() has returned for the first time.
-- 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/321.