GNOME Bugzilla – Bug 311848
Renegotiation broken
Last modified: 2005-08-08 08:41:32 UTC
gst-launch-0.9 videotestsrc ! video/x-raw-yuv,width=200,height=150,format=\(fourcc\)YUY2 ! ffmpegcolorspace ! videoscale ! ximagesink Resize the ximagesink window (to emulate what Totem does), and observe interesting behaviour, such as crashes if you decrease size and garbled output if you increase window size. The negotiation of the new size will fail in ffmpegcolorspace's gst_base_transform_setcaps() in the no_transform_possible case, because it somehow tries to set the new window's size from videoscale on ffmpegcolorspace (all this during gst_pad_alloc_buffer()), this fails because the sizes don't match, and after that, stuff collapses. Here's a backtrace of the no_transform_possible in ffmpegcolorspace:
+ Trace 62039
$1 = ( gchar *) 0x86c7dd8 "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)201, height=(int)152, framerate=(double)30, pixel"... Let's now look at gst-launch-0.9 videotestsrc ! video/x-raw-yuv,width=200,height=150,format=\(fourcc\)YUY2 ! queue ! ffmpegcolorspace ! videoscale ! ximagesink, and resize the window again, which more closely resembles Totem's behaviour; it will directly quit at: ERROR (0x8f19310 - 0:00:02.947686000) queue_dataflow(30547) gstqueue.c(783):gst_queue_loop:<queue0> streaming stopped, reason pad not negotiated ERROR (0x8f19310 - 0:00:02.947818000) queue_dataflow(30547) gstqueue.c(783):gst_queue_loop:<queue0> streaming stopped, reason pad not negotiated ERROR: from element /pipeline0/queue0: streaming stopped, reason pad not negotiated I have the feeling that this is because of ASYNC caps. Problem is that gst_pad_buffer_alloc() calls gst_pad_set_caps(), whereas the normal dataflow also calls this, and those could conflict in some cases. I'd rather see gst_pad_buffer_alloc() only check whether pads can accept the caps, and have actual normal dataflow take care of forward renegotiation afterwards (i.e. move responsibility of renegotiation further down the stack).
Well, I got as far as blaming the trans->delay_configure in basetransform, since the delayed capsnego will obviously never take place. Removing that makes the queue-less pipeline work fine. The queue-containing pipeline will still fail with this, though, and here's where the ASYNC story comes into play again...
Created attachment 49886 [details] [review] attempt Above patch tries to implement it. *) for some reason, it just doesn't work; part of the reason may be that gst_pad_accept_caps() falsely succeeds. *) gst_pad_accept_caps() is not recursive, which makes it practically useless, see above. The reason that it's not recursive is that it calls gst_pad_get_caps() instead of gst_pad_get_allowed_caps(). *) however, gst_pad_get_allowed_caps() leads to deadlocks. More design-wise: *) should videotestsrc ! sizefilter ! queue ! videoscale ! ximagesink have videotestsrc do the scaling, or should videoscale do it, or should videoscale do it for cached buffers of the old size and videotestsrc for the rest? gst_pad_proxy_alloc_buffer() isn't very useful in any of those cases, because it does not renegotiate the sourcepad doing the buffer request. *) in-place elements should never change their sourcepad caps without sinkpad caps being changed and should proxy buffer-alloc calls. Not-in-place elements should not proxy buffer-alloc calls and call those themselves. But what about elements that are sometimes in place and sometimes not (ffmpegcolorspace, videoscale)? How to efficiently implement the ideal behaviour? I don't really know how to make this system work for the non-synchronous case (so anything with a queue in it)...
Andy implemented the above, closing.