Skip to content

Bump go-astits and fix async KLV processing logic#291

Closed
kisasexypantera94 wants to merge 7 commits into
bluenviron:mainfrom
kisasexypantera94:main
Closed

Bump go-astits and fix async KLV processing logic#291
kisasexypantera94 wants to merge 7 commits into
bluenviron:mainfrom
kisasexypantera94:main

Conversation

@kisasexypantera94
Copy link
Copy Markdown

After go-astits PR #72, bounded PES packets (e.g. KLV metadata) can be emitted earlier than unbounded PES packets (e.g. video with PES_packet_length = 0).
This exposed a bug in the MPEG-TS reader where asynchronous KLV data was dropped if no PTS had been received yet.

This PR buffers async KLV data until the first PTS is available, then flushes it with the correct timestamp, instead of dropping it.

@kisasexypantera94
Copy link
Copy Markdown
Author

I'll also add that I ultimately want to add support for ISO639 language codes to mpegts tracks, which was also fixed in the new go-astits release. So that's why I started this pull request haha

@aler9
Copy link
Copy Markdown
Member

aler9 commented Feb 6, 2026

Hello, here are a couple of suggestions:

  • remove the vendor folder
  • limit the maximum count of KLV units inside pendingAsync to prevent the RAM from filling up

Furthermore, this implementation computes the PTS of each incoming KLV unit by using the PTS of the nearest PES with PTS, this is not correct since the PTS should be the one of the last PES before the KLV. Some reasoning is needed.

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 51.72414% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.88%. Comparing base (a7d63af) to head (c12d09e).
⚠️ Report is 16 commits behind head on main.

Files with missing lines Patch % Lines
pkg/formats/mpegts/reader.go 51.72% 13 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #291      +/-   ##
==========================================
+ Coverage   84.54%   85.88%   +1.34%     
==========================================
  Files          92       92              
  Lines        6515     5924     -591     
==========================================
- Hits         5508     5088     -420     
+ Misses        684      575     -109     
+ Partials      323      261      -62     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kisasexypantera94
Copy link
Copy Markdown
Author

Hello, here are a couple of suggestions:

  • remove the vendor folder
  • limit the maximum count of KLV units inside pendingAsync to prevent the RAM from filling up

Furthermore, this implementation computes the PTS of each incoming KLV unit by using the PTS of the nearest PES with PTS, this is not correct since the PTS should be the one of the last PES before the KLV. Some reasoning is needed.

Thanks!

Sorry about the vendor folder, totally missed it, I'll remove it.

Agreed on bounding pendingAsync: I’ll add a max queue size (and/or bytes) and drop with onDecodeError once exceeded to avoid unbounded RAM usage.

Regarding timestamps: for async KLV received before the first timed PES, there is no “last PES before” available. If PCR is available in the adaptation field, we can use it as the initial timeline and timestamp early async KLV against the latest PCR observed, which matches the “last known time before KLV” semantics better.

@kisasexypantera94
Copy link
Copy Markdown
Author

kisasexypantera94 commented Feb 12, 2026

@aler9 Hi!
I’ve updated the branch and added a size limit for pendingAsync. Could you please take a look?

I did not add PCR-based timing for async KLV yet.
One possible approach would be to store the last PCR together with each pending async KLV and later use it to approximate the presentation timestamp (after converting PCR into the PTS domain).

However, doing this correctly would require tracking a PCR snapshot per pending KLV, rather than relying on a single lastPCR, which adds some complexity to what is currently a relatively simple reader.

If you think accurate PCR-based timing is required here, I can implement it.

@aler9
Copy link
Copy Markdown
Member

aler9 commented Feb 13, 2026

Unfortunately i can only confirm the timestamp issue i mentioned before: with this patch and even just with the new go-astits version, timestamp of async KLV units is computed wrongly. Multiple specifications tell that the PTS of an async KLV unit is the one of the previous PES with a PTS. The result of this patch is an incoherent PTS assignment.

Let's suppose the decoder receives this packet sequence:

KLV PES A
VIDEO PES B1 (PES Header)
VIDEO PES B2
VIDEO PES B3
VIDEO PES B4
KLV PES C
VIDEO PES D1 (PES Header)
VIDEO PES D2
VIDEO PES D3
KLV PES D

The ideal behavior would be:

  • discard KLV PES A
  • KLV PES C should be associated with the PTS of VIDEO PES B
  • KLV PES E should be associated with the PTS of VIDEO PES D

Contrarily, this patch and the new go-astits cause the following:

  • KLV PES A is put inside pendingAsync and is then wrongly associated with PTS of VIDEO PES B
  • KLV PES C is put inside pendingAsync (since VIDEO PES D1 is needed to release VIDEO PES B) and then is rightly associated with PTS of VIDEO PES B
  • KLV PES D is released before VIDEO PES D and is wrongly associated with PTS of VIDEO PES B

The correct implementation suggested by multiple sources is to parse the PES Header inside VIDEO PES B1, VIDEO PES D1, release it before the entire PES is returned and use it as lastPTS.

This is tricky since we're using NextData() which does not release single packets (which we now need).

aler9 added a commit that referenced this pull request Mar 1, 2026
Store last valid PTS as soon as possible, by parsing PES headers in
advance, then use this PTS as timestamp of KLV frames without PTS.
@aler9
Copy link
Copy Markdown
Member

aler9 commented Mar 1, 2026

Replaced by #311

@aler9 aler9 closed this Mar 1, 2026
aler9 added a commit that referenced this pull request Mar 1, 2026
Store last valid PTS as soon as possible, by parsing PES headers in
advance, then use this PTS as timestamp of KLV frames without PTS.
aler9 added a commit that referenced this pull request Mar 1, 2026
Store last valid PTS as soon as possible, by parsing PES headers in
advance, then use this PTS as timestamp of KLV frames without PTS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants