Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupting buffering with stopLoad() and then restarting with startLoad() causes a transition to the lowest level #5230

Closed
5 tasks done
bennlich opened this issue Feb 14, 2023 · 5 comments · Fixed by #5241

Comments

@bennlich
Copy link

bennlich commented Feb 14, 2023

What version of Hls.js are you using?

1.3.3

What browser (including version) are you using?

Chrome Version 110.0.5481.77 (Official Build) (64-bit)

What OS (including version) are you using?

Debian 9

Test stream

https://hls-js.netlify.app/demo/

Configuration

{
  "debug": true,
  "enableWorker": true,
  "lowLatencyMode": true,
  "backBufferLength": 90
}

Additional player setup steps

No response

Checklist

Steps to reproduce

  1. Load the hls-js.netlify.com/demo and open the chrome devtools
  2. While the stream is still buffering, call hls.stopLoad() in the console. Notice the level of the fragments being buffered (for me it starts at level 3, then goes up to level 4).
  3. Now call hls.startLoad() to resume buffering. Notice that the level switches down (for me, it switches down to level 2), then slowly switches back up again.

Expected behaviour

I would not expect any level switching to take place after I call hls.startLoad(), since nothing about my bandwidth or streaming capabilities have changed. It seems like manually stopping + starting the load is messing with the automatic level switcher.

What actually happened?

When I call hls.stopLoad() and then hls.startLoad(), the video level switches dramatically downward (from 4 -> 2 in my case).

Console output

main.js:341 Using Hls.js config: {debug: true, enableWorker: true, lowLatencyMode: true, backBufferLength: 90}
logger.ts:74 [log] > Debug logs enabled for "Hls instance"
hls.ts:371 [log] > stopLoad
hls.ts:339 [log] > loadSource:https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
stream-controller.ts:550 [log] > [stream-controller]: Trigger BUFFER_RESET
hls.ts:310 [log] > attachMedia
level-controller.ts:191 [log] > [level-controller]: manifest loaded, 5 level(s) found, first bitrate: 2149280
buffer-controller.ts:142 [log] > 1 bufferCodec event(s) expected
hls.ts:361 [log] > startLoad(-1)
level-controller.ts:272 [log] > [level-controller]: switching to level 3 from -1
level-controller.ts:584 [log] > [level-controller]: Attempt loading level index 3 with URL-id 0 https://test-streams.mux.dev/x36xhzz/url_0/193039199_mp4_h264_aac_hd_7.m3u8
base-stream-controller.ts:1505 [log] > [stream-controller]: STOPPED->IDLE
base-stream-controller.ts:1505 [log] > [subtitle-stream-controller]: STOPPED->IDLE
buffer-controller.ts:791 [log] > [buffer-controller]: Media source opened
stream-controller.ts:615 [log] > [stream-controller]: Level 3 loaded [0,63], cc [0, 0] duration:634.584
buffer-controller.ts:683 [log] > [buffer-controller]: Updating Media Source duration to 634.584
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 0 cc: 0 of [0-63] level: 3, target: 0
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
transmuxer-interface.ts:68 [log] > demuxing in webworker
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 0 p: -1 level: 3 id: 1
        discontinuity: true
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 0
        initSegmentChange: true
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 0 of level 3
blob:https://hls-js.netlify.app/dd51bdfd-d90f-4241-9923-d140067b0f27:633 [log] > Debug logs enabled for "main"
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.64001f/avc1.64001f]
buffer-controller.ts:752 [log] > [buffer-controller]: creating sourceBuffer(audio/mp4;codecs=mp4a.40.2)
buffer-controller.ts:752 [log] > [buffer-controller]: creating sourceBuffer(video/mp4;codecs=avc1.64001f)
audio-stream-controller.ts:118 [log] > [audio-stream-controller]: InitPTS for cc: 0 found from main: 900909
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 0 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 0 of level 3 (frag:[NaN-10.023] > buffer:[0.023-10.008])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
level-controller.ts:272 [log] > [level-controller]: switching to level 4 from 3
level-controller.ts:584 [log] > [level-controller]: Attempt loading level index 4 with URL-id 0 https://test-streams.mux.dev/x36xhzz/url_8/193039199_mp4_h264_aac_fhd_7.m3u8
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->WAITING_LEVEL
stream-controller.ts:615 [log] > [stream-controller]: Level 4 loaded [0,63], cc [0, 0] duration:634.567
base-stream-controller.ts:1505 [log] > [stream-controller]: WAITING_LEVEL->IDLE
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 1 cc: 0 of [0-63] level: 4, target: 10.008
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 1 p: -1 level: 4 id: 1
        discontinuity: false
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 10
        initSegmentChange: false
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 1 of level 4
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.640028/avc1.640028]
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 1 of level 4
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 1 of level 4 (frag:[10.008-20.023] > buffer:[0.023-19.992])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 2 cc: 0 of [0-63] level: 4, target: 19.992
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
hls.stopLoad()
hls.ts:371 [log] > stopLoad
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->STOPPED
base-stream-controller.ts:1505 [log] > [subtitle-stream-controller]: IDLE->STOPPED
undefined
hls.startLoad()
hls.ts:361 [log] > startLoad(-1)
level-controller.ts:584 [log] > [level-controller]: Attempt loading level index 4 with URL-id 0 https://test-streams.mux.dev/x36xhzz/url_8/193039199_mp4_h264_aac_fhd_7.m3u8
base-stream-controller.ts:1505 [log] > [stream-controller]: STOPPED->IDLE
base-stream-controller.ts:1152 [log] > [stream-controller]: SN 1 just loaded, load next one: 2
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 2 cc: 0 of [0-63] level: 4, target: 19.992
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
base-stream-controller.ts:1505 [log] > [subtitle-stream-controller]: STOPPED->IDLE
undefined
stream-controller.ts:615 [log] > [stream-controller]: Level 4 loaded [0,63], cc [0, 0] duration:634.567
transmuxer-interface.ts:68 [log] > demuxing in webworker
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 2 p: -1 level: 4 id: 1
        discontinuity: true
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 19.992380952380874
        initSegmentChange: true
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 2 of level 4
6aa732e9-0808-402e-92d2-cb93ed4f677d:633 [log] > Debug logs enabled for "main"
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.640028/avc1.640028]
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 2 of level 4
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 2 of level 4 (frag:[19.992-30.023] > buffer:[0.023-30.000])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
level-controller.ts:272 [log] > [level-controller]: switching to level 2 from 4
level-controller.ts:584 [log] > [level-controller]: Attempt loading level index 2 with URL-id 0 https://test-streams.mux.dev/x36xhzz/url_6/193039199_mp4_h264_aac_hq_7.m3u8
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->WAITING_LEVEL
stream-controller.ts:615 [log] > [stream-controller]: Level 2 loaded [0,63], cc [0, 0] duration:634.6
base-stream-controller.ts:1505 [log] > [stream-controller]: WAITING_LEVEL->IDLE
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 3 cc: 0 of [0-63] level: 2, target: 30
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
buffer-controller.ts:683 [log] > [buffer-controller]: Updating Media Source duration to 634.600
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 3 p: -1 level: 2 id: 1
        discontinuity: false
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 30
        initSegmentChange: false
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 3 of level 2
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.64001f/avc1.64001f]
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 3 of level 2
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 3 of level 2 (frag:[30.000-40.023] > buffer:[0.023-40.008])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
level-controller.ts:272 [log] > [level-controller]: switching to level 3 from 2
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 4 cc: 0 of [0-63] level: 3, target: 40.008
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 4 p: -1 level: 3 id: 1
        discontinuity: false
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 40.007800453514704
        initSegmentChange: false
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 4 of level 3
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.64001f/avc1.64001f]
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 4 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 4 of level 3 (frag:[40.008-50.023] > buffer:[0.023-49.993])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 5 cc: 0 of [0-63] level: 3, target: 49.993
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 5 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 5 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 5 of level 3 (frag:[49.993-60.023] > buffer:[0.023-60.000])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 6 cc: 0 of [0-63] level: 3, target: 60
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 6 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 6 of level 3
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 6 of level 3 (frag:[60.000-70.023] > buffer:[0.023-70.008])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE
level-controller.ts:272 [log] > [level-controller]: switching to level 4 from 3
base-stream-controller.ts:660 [log] > [stream-controller]: Loading fragment 7 cc: 0 of [0-63] level: 4, target: 70.008
base-stream-controller.ts:1505 [log] > [stream-controller]: IDLE->FRAG_LOADING
transmuxer-interface.ts:201 [log] > [transmuxer-interface, main]: Starting new transmux session for sn: 7 p: -1 level: 4 id: 1
        discontinuity: false
        trackSwitch: true
        contiguous: false
        accurateTimeOffset: true
        timeOffset: 70.00018934240359
        initSegmentChange: false
base-stream-controller.ts:371 [log] > [stream-controller]: Loaded fragment 7 of level 4
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: ISGenerated flag reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: initPTS & initDTS reset
transmuxer-interface.ts:349 [log] > [mp4-remuxer]: reset next timestamp
transmuxer-interface.ts:349 [log] > manifest codec:mp4a.40.2, ADTS type:2, samplingIndex:4
transmuxer-interface.ts:349 [log] > parsed codec:mp4a.40.5, rate:44100, channels:2
base-stream-controller.ts:1505 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1243 [log] > [stream-controller]: Init audio buffer, container:audio/mp4, codecs[selected/level/parsed]=[mp4a.40.2/mp4a.40.2/mp4a.40.5]
stream-controller.ts:1254 [log] > [stream-controller]: Init video buffer, container:video/mp4, codecs[level/parsed]=[avc1.640028/avc1.640028]
transmuxer-interface.ts:349 [log] > [transmuxer.ts]: Flushed fragment 7 of level 4
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:504 [log] > [stream-controller]: Buffered main sn: 7 of level 4 (frag:[70.008-79.957] > buffer:[0.023-79.946])
base-stream-controller.ts:1505 [log] > [stream-controller]: PARSED->IDLE

Chrome media internals output

No response

@bennlich bennlich added Bug Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Feb 14, 2023
@robwalch robwalch added cannot reproduce Works as expected and removed Bug Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Feb 18, 2023
@robwalch
Copy link
Collaborator

robwalch commented Feb 18, 2023

When I call hls.stopLoad() and then hls.startLoad(), the video level switches dramatically downward (from 4 -> 2 in my case).

After calling hls.stopLoad() and then hls.startLoad(), the player restarted loading the same fragment at the same level as the one that was interrupted (note two lines that read Loading fragment 2 cc: 0 of [0-63] level: 4, target: 19.992 before and after).

Only after buffering that fragment, the player then logs a down switch. I see there was a drastic change is estimate. Looking into root-cause.

@robwalch robwalch added Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. Bug Confirmed and removed cannot reproduce Works as expected Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. labels Feb 18, 2023
@robwalch robwalch added this to the 1.4.0 milestone Feb 18, 2023
@robwalch
Copy link
Collaborator

I missed it on the first try, but after a careful review of step 2, used hls.once(Hls.Events.FRAG_LOADING, () => hls.stopLoad()); to interrupt loading.

With trace logs enabled I see that before the restarting and rebuffering the fragment that was interrupted, estimates look OK:

[trace] > [abr] level:4 adjustedbw-bitrate:117164970 avgDuration:9.9 maxFetchDuration:30.8 fetchDuration:0.9

But then we get a rude awakening right after buffering the fragment that was interrupted:

[log] > [stream-controller]: Buffered main sn: 4 of level 4 (frag:[40.008-50.023] > buffer:[0.023-49.993])
[trace] > [abr] level:4 adjustedbw-bitrate:-6221600 avgDuration:9.9 maxFetchDuration:33.7 fetchDuration:191156308873128.2

Best guess is that LoaderState (stats )or some other loader state are not being reset. Need to dig deeper. Thanks for the report.

@robwalch
Copy link
Collaborator

robwalch commented Feb 18, 2023

The is issue is that when startLoad is called, the current level's Playlist is reloaded, replacing stream-controller's LevelDetails with a new fragment list containing new Fragment references and stats. When this happens while the fragment is being loaded, the reference frag.stats used to tally loading/parsing/buffering times is replaced. The default start values of 0 and produce bad results here https://github.com/video-dev/hls.js/blob/master/src/controller/abr-controller.ts#L296

Fix prevents the playlist from being reloaded when it does not need to be, and uses the correct fragment object reference for continuity in the event it would not be (this had been fixed for live where fragment lists are merged, but we never expect to replace loaded playlist data for VOD) e49ff5c

robwalch added a commit that referenced this issue Feb 18, 2023
Warn on currentFrag context reference change and use currentFrag to maintain correct stats ref
Fixes #5230
robwalch added a commit that referenced this issue Feb 18, 2023
Warn on currentFrag context reference change and use currentFrag to maintain correct stats ref
Fixes #5230
robwalch added a commit that referenced this issue Feb 18, 2023
Warn on currentFrag context reference change and use currentFrag to maintain correct stats ref
Fixes #5230
robwalch added a commit that referenced this issue Feb 18, 2023
Warn on currentFrag context reference change and use currentFrag to maintain correct stats ref
Fixes #5230
@bennlich
Copy link
Author

Thank you so much for digging into this so quickly! ❤️

robwalch added a commit that referenced this issue Feb 22, 2023
Warn on currentFrag context reference change and use currentFrag to maintain correct stats ref
Fixes #5230
@robwalch robwalch added the Verify Fixed An unreleased bug fix has been merged and should be verified before closing. label Feb 27, 2023
@bennlich
Copy link
Author

This fix worked for me!

@robwalch robwalch removed the Verify Fixed An unreleased bug fix has been merged and should be verified before closing. label Apr 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants