souphttpsrc: Dynamic blocksize adjustment constantly increases blocksize, causing problems with queue2 buffering
In a pipeline with souphttpsrc and a downstream queue2 element, souphttpsrc's dynamic blocksize adjustment can cause problems, because the blocksize constantly increases.
I was able to see the constant increases with this test command line:
gst-launch-1.0 souphttpsrc location="<HTTP audio stream URL>" ! identity silent=false ! queue2 max-size-buffers=1 max-size-bytes=0 max-size-time=0 ! decodebin ! fakesink sync=true -v
Result:
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (32768 bytes, dts: none, pts: none, duration: none, offset: 39232, offset_end: -1, flags: 00000000 , meta: none) 0x7f7c3ae520
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (65536 bytes, dts: none, pts: none, duration: none, offset: 72000, offset_end: -1, flags: 00000000 , meta: none) 0x7f7c3ae630
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (131072 bytes, dts: none, pts: none, duration: none, offset: 137536, offset_end: -1, flags: 00000000 , meta: none) 0x7f840484b0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (238416 bytes, dts: none, pts: none, duration: none, offset: 268608, offset_end: -1, flags: 00000000 , meta: none) 0x7f840485c0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (262144 bytes, dts: none, pts: none, duration: none, offset: 507024, offset_end: -1, flags: 00000000 , meta: none) 0x7f840486d0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (524288 bytes, dts: none, pts: none, duration: none, offset: 769168, offset_end: -1, flags: 00000000 , meta: none) 0x7f840487e0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (1048576 bytes, dts: none, pts: none, duration: none, offset: 1293456, offset_end: -1, flags: 00000000 , meta: none) 0x7f840488f0
I then disabled the dynamic blocksize adjustment in souphttpsrc to verify. Result:
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (8192 bytes, dts: none, pts: none, duration: none, offset: 6952, offset_end: -1, flags: 00000000 , meta: none) 0x7f905c3300
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (13416 bytes, dts: none, pts: none, duration: none, offset: 15144, offset_end: -1, flags: 00000000 , meta: none) 0x7f905c3410
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (7140 bytes, dts: none, pts: none, duration: none, offset: 28560, offset_end: -1, flags: 00000000 , meta: none) 0x7f905c3520
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (4284 bytes, dts: none, pts: none, duration: none, offset: 35700, offset_end: -1, flags: 00000000 , meta: none) 0x7f905c3630
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (11424 bytes, dts: none, pts: none, duration: none, offset: 39984, offset_end: -1, flags: 00000000 , meta: none) 0x7f980494b0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (7140 bytes, dts: none, pts: none, duration: none, offset: 51408, offset_end: -1, flags: 00000000 , meta: none) 0x7f980495c0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (5712 bytes, dts: none, pts: none, duration: none, offset: 58548, offset_end: -1, flags: 00000000 , meta: none) 0x7f980496d0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (4284 bytes, dts: none, pts: none, duration: none, offset: 64260, offset_end: -1, flags: 00000000 , meta: none) 0x7f980497e0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (1428 bytes, dts: none, pts: none, duration: none, offset: 68544, offset_end: -1, flags: 00000000 , meta: none) 0x7f980498f0
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (2856 bytes, dts: none, pts: none, duration: none, offset: 69972, offset_end: -1, flags: 00000000 , meta: none) 0x7f98049a00
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (4284 bytes, dts: none, pts: none, duration: none, offset: 72828, offset_end: -1, flags: 00000000 , meta: none) 0x7f98049b10
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (2856 bytes, dts: none, pts: none, duration: none, offset: 77112, offset_end: -1, flags: 00000000 , meta: none) 0x7f98049c20
/GstPipeline:pipeline0/GstIdentity:identity0: last-message = chain ******* (identity0:sink) (5712 bytes, dts: none, pts: none, duration: none, offset: 79968, offset_end: -1, flags: 00000000 , meta: none) 0x7f98049d30
Commit 1081a2ee in gst-plugins-good at least applies some degree of limitation, but the buffer size still gets big enough to match the capacity of queue2. The result is that in typical HTTP streaming pipelines, the queue2 then only has room for one incoming buffer, so the buffer fill level constantly switches between 0% and 100%. (Note: The test pipeline above artificially limits the queue2 capacity to 1 buffer, but this is only for testing purposes.) Since applications typically pause when the buffering message reports <100%, this ultimately results in a stuttering playback, because the player pauses & unpauses all the time.
The proper solution perhaps would be a new type of query sent downstream by souphttpsrc to ask what max buffer size is allowed. If queue2 exists downstream, it could then pick a number that guarantees that at least N buffers fit into it. Aside from that, some sort of "max-dynamic-blocksize" property would perhaps make sense. It would act as a hard limit for dynamically adjusted buffer sizes. Default value 0 (= no limit). If it is set to a value smaller than that of the blocksize property, it would result in a GObject warning (since that would make no sense).