GNOME Bugzilla – Bug 551509
gst_base_transform_prepare_output_buffer: assertion failed: (*out_buf != NULL)
Last modified: 2008-09-28 21:19:37 UTC
GST_DEBUG="*:4" G_DEBUG="fatal_warnings" gdb --args gst-launch-0.10 -v filesrc location=test.jpg ! queue ! image/jpeg, framerate=\(fraction\)15/1 ! jpegdec ! freeze ! ffmpegcolorspace ! xvimagesink 0:00:10.161792872 26686 0x81d4d10 DEBUG GST_CAPS gstpad.c:2601:gst_pad_get_allowed_caps:<capsfilter0:src> allowed caps image/jpeg, framerate=(fraction)15/1, width=(int)[ 16, 4096 ], height=(int)[ 8, 4096 ] 0:00:10.161833313 26686 0x81d4d10 DEBUG capsfilter gstcapsfilter.c:336:gst_capsfilter_prepare_buf:<capsfilter0> Have unfixed output caps image/jpeg, framerate=(fraction)15/1, width=(int)[ 16, 4096 ], height=(int)[ 8, 4096 ] ** ** ERROR:(gstbasetransform.c:1144):gst_base_transform_prepare_output_buffer: assertion failed: (*out_buf != NULL)
This is because of jpegdec having width and heigh on its sink-caps. If I determine sizes and use full caps, I don't get the gstbasetransform-assertion, but 0:00:00.121062159 27204 0x81cbfd0 WARN jpegdec gstjpegdec.c:1042:gst_jpeg_dec_chain:<jpegdec0> error: Failed to decode JPEG image 0:00:00.121425424 27204 0x81cbfd0 WARN jpegdec gstjpegdec.c:1042:gst_jpeg_dec_chain:<jpegdec0> error: Error #69: Unsupported marker type 0x%02x 0:00:00.121537736 27204 0x81cbfd0 WARN basesrc gstbasesrc.c:2234:gst_base_src_loop:<filesrc0> error: Internal data flow error. 0:00:00.121604089 27204 0x81cbfd0 WARN basesrc gstbasesrc.c:2234:gst_base_src_loop:<filesrc0> error: streaming task paused, reason error (-5) ERROR: from element /GstPipeline:pipeline0/GstJpegDec:jpegdec0: Failed to decode JPEG image setting the framerate via capsfilter is the method we document for pngdec/jpegdec to not eos after first picture. This is needed to produce a stream with freeze to e.g. overlay an image on a video with videomixer.
> setting the framerate via capsfilter is the method we document for > pngdec/jpegdec to not eos after first picture. This is needed to > produce a stream with freeze to e.g. overlay an image on a video > with videomixer. Where is this documented? If you put a caps filter *before* jpegdec and set a framerate there, jpegdec will assume the input is a stream of multiple jpeg pictures and packetised, ie. one-buffer-per-image. The above 'failed to decode' error is due to you not specifying the right block-size on the filesrc, so jpegdec expects a full picture as input but only gets a chunk of it. Basetransform shouldn't abort of course, this definitly needs fixing.
Okay, I then I was misunderstanding. I've tried to overlay a video with an image and what I understood is that putting the capsfilter with a framerate infront of jpegdec/pngdec will tell them to not eos, so that e.g. freeze and make a stream of the image. I think we have some conceptual problmes with that, but that a different issue. Lets have a look on the basetransform in the scope of this report only.
Created attachment 118606 [details] [review] unit test which reproduces the issue
I think we should commit the unit test, and then be forced to fix it...
Created attachment 119338 [details] [review] alternative patch I think the real bug here is that capsfilter can't apply incompletely specified caps to a buffer, so in the case where it's been asked to (the incoming buffers have no caps, but capsfilter has some filtercaps) it should error out if the result is not completely fixed. As an aside, I converted the assert in basetransform into a GST_FLOW_ERROR, because while the sub-class should be providing a buffer or erroring in all cases, it doesn't have to lead to an assert when a runtime error would be better. Changed the unit test to check that in fact the test case does *not* succeed in producing output buffers.
all right!
With previous revisions, such pipeline was RUNNING : gst-launch -v udpsrc ! capsfilter caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d8800650584121463000001b24c61766335312e34382e30" ! rtpmp4vdepay ! fakesink With new basetransform, Jan Schmidt GST_FLOW_ERROR occurs. Moreover : This, gst-launch -v udpsrc ! capsfilter caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d8800650584121463000001b24c61766335312e34382e30" ! rtpmp4vdepay ! ffdec_mpeg4 ! xvimagesink does not work, but setting the caps property of udpsrc displays the video : gst-launch -v udpsrc caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, config=(string)000001b001000001b58913000001000000012000c48d8800650584121463000001b24c61766335312e34382e30" ! rtpmp4vdepay ! ffdec_mpeg4 ! xvimagesink this works fine too : gst-launch -v udpsrc ! capsfilter caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)1, *payload=96*, config=(string)000001b001000001b58913000001000000012000c48d8800650584121463000001b24c61766335312e34382e30" ! rtpmp4vdepay ! ffdec_mpeg4 ! xvimagesink And it works with whatever payload which is rtpmp4vdepay compatible (dynamic payload) Do you think that not running is the right thing to do (because of caps negotiation failure on payload), or something was broken ? Previously, basetransform was allocating buffer when subclass did not. Why no more ?
As you noticed, the top pipelines fail to supply the payload parameter. I'm not sure how that worked before. I expected that it should fail because the buffers didn't have a parameter that the sink pad template had requested.
Yes, of course, according to caps policy, this obviously must fail. But payload is not necessary for the pipeline to work. So payload cap in rtpmp4gdepay is not mandatory, this is just a restriction to dynamic payload. Should payload be removed of rtp depacketizer / packetizer caps and considered optional as profile-level-id and config already are ? I did not see any other case of such behavior, but considering a pipeline cannot work because of a non useful parameter is a bit weird. I think it was working before, because basetransformed provided a buffer whenever the subclass did not, and payload is unused ny downstream elements ...
Anyone else want to weigh in here? Should I just restore the old behaviour for this case, or is the test case buggy?
It's not unreasonable to fail when you specify an incomplete capsfilter so I'm happy with this. Theoretically, the depayloader should fail if there is no payload type set either, don't know why it does not fail... Another option is to remove the remaining unfixed properties from the caps in capsfilter?
Oh right, it does not fail because we check intersection on caps instead of a subset.
Also, capsfilter is not meant to set caps on buffers but to _filter out_ the different possibilities. In this use case, a capsfilter is clearly the wrong thing to use.
so effectively a sink pad accepts any caps where the media type matches and none of the supplied properties directly conflict? We've deliberately enabled capsfilter to set caps in the specific case of the input buffers having no caps of their own, but in general - yes you're right.
This is not blocking for me, this was just a different behavior I wanted to point out. Fell free to commit this new behavior.
OK, how about this version - it's the same as the first patch, but it restores the basetransform behaviour that a subclass can return OK without preparing a special buffer and it will fall back to pad_alloc.
Created attachment 119462 [details] [review] updated patch
OK, committing as is and making a new pre-release. Can fix it and make another if you think it's not right. 2008-09-28 Jan Schmidt <jan.schmidt@sun.com> * libs/gst/base/gstbasetransform.c: * plugins/elements/gstcapsfilter.c: * tests/check/Makefile.am: * tests/check/elements/.cvsignore: * tests/check/elements/capsfilter.c: Fix assertion in basetransform when the subclass chooses not to allocate a buffer in prepare_buffer(), and make capsfilter error out cleanly if requested to apply caps that don't completely specify the buffer. Fixes #551509