Closed Bug 2026875 Opened 4 months ago Closed 4 months ago

Firefox 149 regression: HLS playback starts only after manual seeking

Categories

(Core :: Audio/Video: Playback, defect, P2)

Firefox 149
All
Unspecified
defect

Tracking

()

VERIFIED FIXED
151 Branch
Tracking Status
firefox-esr140 --- unaffected
firefox149 --- wontfix
firefox150 --- verified
firefox151 --- verified

People

(Reporter: antonytomasiny456, Assigned: alwu)

References

(Regression)

Details

(Keywords: regression)

Attachments

(3 files, 9 obsolete files)

416.00 KB, text/x-log
Details
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:149.0) Gecko/20100101 Firefox/149.0

Steps to reproduce:

  1. Update Firefox from version 148 to 149 on Windows 10.

  2. Open an affected HLS video page.

  3. Click Play.

  4. Observe that the video buffers and .ts segments load, but playback does not start.

  5. Manually seek the timeline.

  6. Observe that playback starts only after seeking.

Actual results:

The video buffers normally and .ts segments are downloaded, but playback does not start after pressing Play. It only starts after I manually seek the timeline.

Expected results:

The video should start playing immediately after pressing Play, without requiring manual seeking.

The Bugbug bot thinks this bug should belong to the 'Core::Audio/Video: Playback' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Audio/Video: Playback
Product: Firefox → Core

I have the same issue on Linux and Windows with a fresh profile.
After the upgrade to Firefox 149 watching video from Jellyfin with the official jellyfin-web interface, both version 10.11.6.
Some videos stall immediately and start playing ~6 seconds in. Some stall immediately start playing ~6 seconds in and then stall again about 6 seconds later. Then I can wait about 3 minutes and it will continue playing or I can seek manually. Some videos work.

Attached file media-playback.log

Comment on attachment 9559296 [details]
media-playback.log

Log of a video stalling immediately and starting playback about 6 seconds in and then stalling again

Could you help us out by trying to capture a Firefox performance profile when this happens?

Visit https://profiler.firefox.com/ for more information and to enable the profiling toolbar button. When capturing a profile, please follow these steps -

  1. Navigate to about:logging
  2. In the logging preset drop down, select 'Media playback' and then click 'Set Log Modules'
  3. Click 'Start Logging' and conduct your testing. Keep this part short. Capture the issue well.
  4. Upload the resulting performance profile and post the url provided to this bug.

Thanks!

https://share.firefox.dev/4vdQdcH

This captures the skipping of the first 6 seconds, playing for 6 seconds and then stalling again.

Keywords: regression
Severity: -- → S2
Priority: -- → P2
Flags: needinfo?(padenot)

Reproduced in a clean separate Firefox profile.

https://share.firefox.dev/413bVSG

Assignee: nobody → alwu

The guard added by bug 2014888 to prevent a diagnostic assert was too broad:
it suppressed legitimate data requests needed after WAITING_FOR_DATA retries
in HLS/MSE slow-network scenarios, causing seeks to stall until a subsequent
data notification re-drove the pipeline.

SKIP_BMO_CHECK

Attachment #9560125 - Attachment is obsolete: true
Attachment #9560126 - Attachment description: Bug 2026875 - Add MSE mochitest for seek-stall regression with delayed data. r?padenot → WIP: Bug 2026875 - Add MSE mochitest for seek-stall regression with delayed data. r?padenot
Attachment #9560127 - Attachment description: Bug 2026875 - Fix seek stall when data arrives during in-flight demuxer seek. r?padenot → WIP: Bug 2026875 - Fix seek stall when data arrives during in-flight demuxer seek. r?padenot
Attachment #9560125 - Attachment is obsolete: false
Attachment #9560125 - Attachment description: Bug 2026875 - Fix seek stall when data arrives during in-flight demuxer seek. r?padenot → WIP: Bug 2026875 - Fix seek stall when data arrives during in-flight demuxer seek. r?padenot
Attachment #9560127 - Attachment is obsolete: true
Attachment #9560126 - Attachment is obsolete: true
Attachment #9560125 - Attachment is obsolete: true

I tested the Linux build with a fresh profile and it has the same behavior as before.
It skips the first 6 seconds, plays for 6 seconds and then stalls. Manually seeking past that point by 3 seconds continues playback.

Flags: needinfo?(bugzilla.qgqjr)

I tried the Windows try build, but I could not properly test playback because the build crashes on my system before I can complete the reproduction steps.

So at the moment I cannot confirm whether the fix works in this build.

Relevant warnings before the crash:

[Parent 15396, Main Thread] WARNING: IPC message 'PContent::Msg_NotifyProcessPriorityChanged' discarded: actor cannot send

[Parent 15396, IPC I/O Parent] WARNING: Dropping message '<null>'; no connection to unknown peer ...

[Parent 15396, IPC I/O Parent] WARNING: Rejecting introduction request ... for unknown peer ...

[Parent 15396, WindowsVsyncThread] WARNING: DwmComposition dynamically disabled, falling back to software timers

If needed, I can provide the full log output.

Flags: needinfo?(antonytomasiny456)

Could anyone provide a video link that would help me debug this issue more deeply? Thanks!

Flags: needinfo?(antonytomasiny456)

This video from the Jellyfin demo instance works normally on firefox <149, but in Firefox 149, seeking to before 0:08 is not possible, and if you wait and let it play for a bit, it will freeze.

https://demo.jellyfin.org/stable/web/#/details?id=f717d85df782816c2ab75423e32f740b&serverId=f0b3381645f04afb9a0e392e74b6a1b0

(In reply to Kyle Scheuing from comment #15)

This video from the Jellyfin demo instance works normally on firefox <149, but in Firefox 149, seeking to before 0:08 is not possible, and if you wait and let it play for a bit, it will freeze.

https://demo.jellyfin.org/stable/web/#/details?id=f717d85df782816c2ab75423e32f740b&serverId=f0b3381645f04afb9a0e392e74b6a1b0

This requires login, do you have any other open example I can try with? Thanks!

Flags: needinfo?(kyle)

(In reply to Alastor Wu [:alwu] from comment #16)

(In reply to Kyle Scheuing from comment #15)

This video from the Jellyfin demo instance works normally on firefox <149, but in Firefox 149, seeking to before 0:08 is not possible, and if you wait and let it play for a bit, it will freeze.

https://demo.jellyfin.org/stable/web/#/details?id=f717d85df782816c2ab75423e32f740b&serverId=f0b3381645f04afb9a0e392e74b6a1b0

This requires login, do you have any other open example I can try with? Thanks!

I have only experienced the problem with Jellyfin, so I don't have any other examples. There's no password for the demo account, so you should be able to use that. If the login barrier is a hindrance to debugging, let me know and I'll see what I can do.

Flags: needinfo?(kyle)
Duplicate of this bug: 2029042

I can't get a jellyfin stream to play. Just sits there. Note this is on a Mac. I'll check windows 11.

https://demo.jellyfin.org/stable/web/#/details?id=f717d85df782816c2ab75423e32f740b&serverId=f0b3381645f04afb9a0e392e74b6a1b0

Flags: needinfo?(alwu)

Same on win11. js console -

[MediaSessionSubscriber] ignoring local player update main.jellyfin.bundle.js:2:182999
Requesting url without automatic networking: https://demo.jellyfin.org/stable/Sessions/Playing/Progress node_modules.jellyfin-apiclient.bundle.js:2:14622
[MediaSessionSubscriber] ignoring local player update main.jellyfin.bundle.js:2:182999
Requesting url without automatic networking: https://demo.jellyfin.org/stable/Sessions/Playing/Progress node_modules.jellyfin-apiclient.bundle.js:2:14622
Uncaught (in promise) DOMException: The fetching process for the media resource was aborted by the user agent at the user's request. [MediaSessionSubscriber] ignoring local player update main.jellyfin.bundle.js:2:182999
Requesting url without automatic networking: https://demo.jellyfin.org/stable/Sessions/Playing/Progress node_modules.jellyfin-apiclient.bundle.js:2:14622
[MediaSessionSubscriber] ignoring local player update main.jellyfin.bundle.js:2:182999
Requesting url without automatic networking: https://demo.jellyfin.org/stable/Sessions/Playing/Progress node_modules.jellyfin-apiclient.bundle.js:2:14622
Uncaught (in promise) DOMException: The fetching process for the media resource was aborted by the user agent at the user's request.

Same issue in Plex using "alternate streaming protocol for video playback" in the Plex Web Application (app.plex.tv) Debug settings, which forces HLS streaming (instead of DASH). Can reproduce with OTA Live TV streaming which requires transcoding from MPEG2 to h264 for browser playback. The possible delay introduced by the transcoder may be causing the stall, but the video will not begin playback on initial load. The firefox developer window reports "[Player] A non-critical HLSjs error occurred: bufferStalledError". Manually seeking back a few seconds will allow the video to play (typically). Also affects DVR recordings in Plex, as they too are stored in MPEG2 and must be transcoded.

Ok, now I can reproduce the error, keep my NI, I will report back what I found later.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(alwu)

Same issue on Windows 11 in Firefox 149.0.

First 10 seconds skipped of any video in my case. Seek is also broken.

Unfortunately this doesn't seem to help for me, the first 6-10s segment always gets skipped, even when trying to seek back to the start, with the same error as mentioned above: bufferStalledError

Could you help to capture a media profile by following this instruction? Thanks!

Flags: needinfo?(arno.wiest)

Absolutely, here it is: https://share.firefox.dev/4crGyHS

I tried seeking to the start a few times to trigger the error.
Also I'm on Linux (CachyOS / Arch), if that's relevant

Flags: needinfo?(arno.wiest)

Does this happen on every video, or only on specific ones? Also, when the video gets stuck, have you tried seeking forward to a later timestamp (not the start)? Thanks!

Flags: needinfo?(arno.wiest)

After trying out some videos in my Jellyfin library, it does seem like some videos aren't affected, but I cannot find any commonalities between those. It's not one specific codec that doesn't work, or something like that.

Specifically the video from above, from the demo jellyfin instance has the same problem, even on the new build.

And this one actually works fine, very odd...

Flags: needinfo?(arno.wiest)

It looks like your issue may be different. Based on your profile, playback does start, but Jellyfin appears to repeatedly perform seeks, interrupting playback multiple times. Have you only encountered this issue on Jellyfin, or can you reproduce it on other websites as well?

Flags: needinfo?(arno.wiest)

(In reply to Alastor Wu [:alwu] from comment #26)

Can anyone try these builds to see if it fixes the problem or not? Thanks!

Windows : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/Iizn6jpHSn24InId2lXCUQ/runs/0/artifacts/public/build/target.zip
Linux : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/GOJFp2zPTMyLfKI1XQJSiA/runs/0/artifacts/public/build/target.tar.xz
MacOS : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/BFxgSDAWRwOB94iK5naacg/runs/0/artifacts/public/build/target.dmg

I'm seeing an improvement on the Linux build, it still skips the first 3 seconds but seems to play ok after that (at least for a minute which is way further than it did before)

I do think this is the same issue, or at least part of it. It also started happening in this version and is also connected to HLS.

For me, I have only seen this with jellyfin, however that is also the only video platform I use, besides youtube.

And for me, on videos that have such problems, it's been 2 specific issues:

  • playback starts at the 6-10s mark, seeking back to the very start does not work, it just keeps restarting at that same mark.
  • sometimes, not always, the video will then halt at around the 16-20s mark and will not continue, unless I seek forwards and it will keep going at around the 40-50s mark

So basically, that first segment is always unreachable, and sometimes a second segment is also unseekable.

As for the repeated seeks in my trace: I manually seemed back to the very start of the video, to trigger that first issue, where it wouldn't go to the very start.

In this instance, I did not get the 2nd issue, of the playback stopping at around the 16-20s mark

Flags: needinfo?(arno.wiest)

That latest build fixed it for me. Thanks.

Yuup, for me too, thanks for the amazing work!

(In reply to Alastor Wu [:alwu] from comment #35)

How about this build? Could anyone help me try it again? Thanks!

Linux : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/Sw1O59MmRpmsxyVzdfdW3w/runs/0/artifacts/public/build/target.tar.xz
MacOS : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/cwTaO30MQ1yjT3mB3pftGA/runs/0/artifacts/public/build/target.dmg
Windows : https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/EYPqP__CSPmAYtkLhtpaRQ/runs/0/artifacts/public/build/target.zip

This build fixes the issue for me too on Windows 11.

Note that the issue affects Firefox 149 too, not sure why it is tagged unaffected. Requesting uplift and 149.0.1 if possible.

Thanks, I’ll submit my patches later. Since this issue is quite complex, I don’t expect them to be uplifted to 149 right away. They’ll need some time to ensure there’s no breakage, but I will aim to uplift them to 150.

Flags: needinfo?(antonytomasiny456)

On HLS streams where the buffered range starts at a non-zero timestamp,
a seek can stall indefinitely. When data is not yet available at the
seek target, MFR issues an internal seek to re-prime the decoder from
the nearest keyframe, decoding and dropping frames until it reaches the
target. MFR correctly identifies when the target frame arrives, but
fails to notify MDSM that the data it was waiting for is now available,
leaving the player stuck.

This patch clears the waiting state and resolves the pending WaitForData
promise when the frame-drop loop reaches its target.

When the MSE buffer starts at a non-zero timestamp, MDSM's BufferingState
calls RequestVideoData with time=0. The MSE demuxer has no data at t=0 and
returns WAITING_FOR_DATA immediately, causing a permanent stall.

Pass GetMediaTime() to RequestVideoData so MFR seeks to and decodes from
the actual playback position.

When MSE coded-frame processing removes frames from a previous segment
(spec-correct behaviour), the next available sample can be far ahead of
the expected timestamp. GetSample treats this as a missing-data gap and
returns nullptr, causing WAITING_FOR_DATA even though the data is buffered.

Add aAllowGapCrossing parameter to the private GetSample; when true, return
the sample if it falls within the sanitized buffered ranges instead of
treating the gap as missing data.

When filling silence before a time-gapped audio frame, the cap on
missingFrames was computed in output-rate frames, but missingFrames is
in input-rate frames. On a 2x resampling path this made the silence
buffer twice the ring-buffer capacity; the overflow was silently dropped,
writing only half the required silence, draining the ring buffer and
causing MDSM to enter BUFFERING permanently.

Some encoders encode the AAC pre-roll delay as 2^64-N in the tfdt
baseMediaDecodeTime field (e.g. 2^64-2048 for a 2048-sample delay).
Firefox's CheckedInt rejects this as out-of-range for int64_t, causing
ParseTrun to return Err and the entire audio moof to be skipped.

Reinterpret the unsigned tfdt as a signed int64_t before assigning to
CheckedInt so that 2^64-N becomes -N (a small negative value). The
existing edit-list mechanism then subtracts mMediaStart to compute the
correct presentation timestamps for the pre-roll frames, matching the
behaviour of Chromium's track_run_iterator.cc.

Accumulation overflow during per-sample decode time computation is still
caught by the isValid() check in the loop below.

Blocks: 2030127
Attachment #9565977 - Attachment is obsolete: true
Attachment #9565978 - Attachment is obsolete: true
Attachment #9565979 - Attachment is obsolete: true
Attachment #9565981 - Attachment is obsolete: true
Attachment #9565982 - Attachment is obsolete: true
Attachment #9567275 - Attachment description: WIP: Bug 2026875 - Fix MoofParser discarding audio fragments with AAC encoder delay tfdt. → Bug 2026875 - Fix MoofParser discarding audio fragments with AAC encoder delay tfdt.
Attachment #9567352 - Attachment is obsolete: true

firefox-beta Uplift Approval Request

  1. Click the image above demo, which will leads you to a video selection page
  2. Click any episode to start playback
  3. Video should start playing successfuly
  • Risk associated with taking this patch: low
  • Explanation of risk level: Only a value conversion from unsigned to signed, it doesn't introduce any behavior/structural change.
  • String changes made/needed?: No.
  • Is Android affected?: unknown
Attachment #9567846 - Flags: approval-mozilla-beta?
Flags: qe-verify+
Pushed by alwu@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/f7404a016180 https://hg.mozilla.org/integration/autoland/rev/c8c2a4b76d40 Fix MoofParser discarding audio fragments with AAC encoder delay tfdt. r=padenot
Status: NEW → RESOLVED
Closed: 4 months ago
Resolution: --- → FIXED
Target Milestone: --- → 151 Branch
Hardware: Unspecified → All
Summary: Firefox 149 regression: HLS playback starts only after manual seeking on Windows 10 → Firefox 149 regression: HLS playback starts only after manual seeking
QA Whiteboard: [uplift][qa-ver-needed-c151/b150]
Duplicate of this bug: 2027038
Duplicate of this bug: 2028504
Regressed by: 2004835

Thanks for fixing the issue.

I was working on a fix for this as part of bug 2028504 and realized this got fixed recently.

Bug 2004835 introduced the issue. It's my change, sorry for introducing a regression: I didn't realized this could happen.

I agree this should be fixed, since we had several reports from the fields about media files which become non playable after that change, which are furthermore playable in other browsers.

For the record, just to give a bit of background on why I thought my change initially made sense (quoting what I said in bug 2027232 comment 4 and 6.

Those files don't seem to be spec compliant, since the spec requires unsigned integers:

Quoting ISO/IEC 14496-12:

8.8.12.2 Syntax

aligned(8) class TrackFragmentBaseMediaDecodeTimeBox
  extends FullBox(‘tfdt’, version, 0) {
  if (version==1) {
    unsigned int(64) baseMediaDecodeTime;
  } else { // version==0
    unsigned int(32) baseMediaDecodeTime;
  }
}

I think it works on Chrome because it has the same behavior as before bug 2004835 was fixed in Firefox: it does an implicit conversion from uint64_t to int64_t when parsing those boxes.

Here:
https://chromium.googlesource.com/chromium/src/media/+/0cdde77f5a42025c4dfac9802607f2e632e4c7d6/mp4/track_run_iterator.cc#134

With definition of the function here (which takes an int64_t and perform implicit conversion):
https://chromium.googlesource.com/chromium/src/media/+/0cdde77f5a42025c4dfac9802607f2e632e4c7d6/mp4/track_run_iterator.cc#15
And definition of the variables here (which is uint64_t as specified in the specification):
https://chromium.googlesource.com/chromium/src/+/88d5fa137b3569d0297719f7def757731fb37b87/media/formats/mp4/box_definitions.h#456

Attachment #9567846 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
See Also: → 2028102

Reproduced the issue in Release 149.0.2
Verified - Fixed in Beta 150.0b9(build id: 20260413090345) and Nightly 151.0a1(build id: 20260413220854). The Jellyfin videos are playing accordingly in the mentioned Fx versions.

Status: RESOLVED → VERIFIED
Has STR: --- → yes
QA Whiteboard: [uplift][qa-ver-needed-c151/b150] → [uplift][qa-ver-done-c151/b150]
Flags: qe-verify+
QA Contact: ailea
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: