Skip to content

[mpegts] Only auto-register PAT PIDs and validate the PSI section header - PlutoTv fails on ads for 21.5.21.1#2083

Closed
wmdebrito wants to merge 1 commit into
xbmc:Omegafrom
wmdebrito:fix/mpegts-restrict-psi-autoregister-to-pat
Closed

[mpegts] Only auto-register PAT PIDs and validate the PSI section header - PlutoTv fails on ads for 21.5.21.1#2083
wmdebrito wants to merge 1 commit into
xbmc:Omegafrom
wmdebrito:fix/mpegts-restrict-psi-autoregister-to-pat

Conversation

@wmdebrito

Copy link
Copy Markdown

Description

Commit 59fd1b3 ("Accept any PID number not only PAT with PID 0") made ProcessTSPacket auto-register any first-seen PID as a PSI packet when its payload bytes matched table_id 0x00 (PAT) or 0x02 (PMT).

Motivation and context

The PMT case is both redundant and unsafe: PMT PIDs are always registered by the PAT parser (parse_ts_psi, table_id 0x00) before any PMT packet arrives, so a valid PMT PID never reaches this branch. The only PID that does is a non-PSI PID whose payload happens to begin with table_id 0x02 -- common on discontinuous /corrupt live HLS-TS. Such a PID is then misparsed as a PMT, triggers a spurious program change, corrupts the demux state, and crashes on the next TSResync() in AP4_ByteStream::Read (SIGSEGV).

Fix: auto-register only when the PID carries the start of a PAT section, and validate the section header (reserved bits set, sane section_length) before trusting it. This preserves the original intent (accept a PAT not on PID 0) while removing the crash. No regression observed on DASH or well-formed TS.
############### LOG FILE ################
14:00:42.107 T:418559 inputstream.adaptive: [AS-16] Download finished: .../hls/stream-13259.ts (2223852 byte)
14:00:42.108 T:418559 CurlFile::Open - https://redebrasil.nuvemplay.live/hls/stream-13260.ts
14:00:42.255 T:1258 inputstream.adaptive: Download finished: .../hls/stream.m3u8 (438 byte)
14:00:42.256 T:1258 inputstream.adaptive: Manifest saved to: .../manifest_1782493242_child-video.txt
14:00:42.376 T:1170 warning: ActiveAE - large audio sync error: -1007.649115
14:00:42.426 T:1170 warning: ActiveAE - large audio sync error: -1006.661655
... (≈20 consecutive ~-1007 ms audio-sync warnings) ...
14:00:42.626 T:418559 inputstream.adaptive: [AS-16] Download finished: .../hls/stream-13260.ts (2137936 byte)
14:00:42.628 T:418559 CurlFile::Open - https://redebrasil.nuvemplay.live/hls/stream-13261.ts
...
14:00:43.126 T:1170 ActiveAE::SyncStream - average error -989.564397 above threshold of 200.000000
14:00:43.379 T:1170 ActiveAE::SyncStream - average error -0.017912 below threshold of 30.000000
14:00:43.536 T:418994 inputstream.adaptive: IsLastSegment: Check for last segment (period end PTS: 6000, segment end PTS: 6000)
############### END LOG FILE ################

How has this been tested?

A custom version with those changes was built and installed on Kodi.

The same stream that was failing after a few minutes, every time, now run for more than 24h without crashing. Same thing was happening with PlutoTv when ads were playing, it crashed every time, but now works fine.

Screenshots (if appropriate):

Types of change

  • Bug fix (non-breaking change which fixes an issue)
  • Clean up (non-breaking change which removes non-working, unmaintained functionality)
  • Improvement (non-breaking change which improves existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that will cause existing functionality to change)
  • Cosmetic change (non-breaking change that doesn't touch code)
  • None of the above (please explain below)

Checklist:

  • I have read the Contributing document
  • My code follows the Code Guidelines of this project
  • My change requires a change to the Wiki documentation
  • I have updated the documentation accordingly

Commit 59fd1b3 ("Accept any PID number not only PAT with PID 0") made
ProcessTSPacket auto-register any first-seen PID as a PSI packet when its
payload bytes matched table_id 0x00 (PAT) or 0x02 (PMT).

The PMT case is both redundant and unsafe: PMT PIDs are always registered by
the PAT parser (parse_ts_psi, table_id 0x00) before any PMT packet arrives, so
a valid PMT PID never reaches this branch. The only PID that does is a non-PSI
PID whose payload happens to begin with table_id 0x02 -- common on discontinuous
/corrupt live HLS-TS. Such a PID is then misparsed as a PMT, triggers a spurious
program change, corrupts the demux state, and crashes on the next TSResync() in
AP4_ByteStream::Read (SIGSEGV).

Fix: auto-register only when the PID carries the start of a *PAT* section, and
validate the section header (reserved bits set, sane section_length) before
trusting it. This preserves the original intent (accept a PAT not on PID 0)
while removing the crash. No regression observed on DASH or well-formed TS.

Author: Wagner Brito <wagnerbrito@gmail.com>
@wmdebrito wmdebrito changed the title [mpegts] Only auto-register PAT PIDs and validate the PSI section header [mpegts] Only auto-register PAT PIDs and validate the PSI section header - PlutoTv fails on ads for AI 21.5.21.1 Jun 27, 2026
@kodiai

kodiai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Decision: APPROVE

Issues: none

Evidence:

  • Review prompt covered 1 changed file.
Review Details
  • Review plan: ready hash=5978d6c95682 route=standard task=review.full files=1 lines=24(local-diff) budget=na/754s gates=3/3 publish=canonical-visible-surface graph=skipped candidates=preferred doctrine=disabled/0/0/0 reasons=disabled

  • Review reducer: ready input=1 kept=1 suppressed=0 rewritten=0 deprioritized=0 lowConfidence=0 auditEvents=0 severityDemoted=0 graphValidated=0 graphUncertain=0 doctrine=disabled/0/0/0 reasons=disabled

  • Review candidates: shadow recorded=1 rejected=0 errors=0 artifact=present repo=xbmc-inputstream.adaptive pr=2083 key=kodiai-review-output:v1:inst-109141824:xbmc-inputstream.adaptive:pr-2083:action- delivery=47694cc0-7241-11f1-8532-8a2d327b040d

  • Review candidate publication: mode=blocked approved=1 rewritten=0 publishable=0 nonPublishable=1 fixBlocked=1 published=0 directFallback=0 reasons=fix-eligibility-blocked movedToDetails=0 detailsOmitted=0 buckets=blocked:1:fix-eligibility-blocked+missing-replacement

  • M072 candidate publication bridge: status=denied; bridgeVersion=candidate-publication-bridge.v1; bridgeId=candidate-publication-record:5dad272f36c07d740602294549b0f3f2; recordKey=candidate-publication-record:5dad272f36c07d740602294549b0f3f2; correlationKey=candidate-publication-bridge:7c4bc3f5700d5fdf1903fc7da79f2031; source=review-handler-publication; candidateRef=candidate-publication-summary-a747b65a; verification=none; counts=candidateCount:0,evidenceCount:0,verifiedCount:0,partiallyVerifiedCount:0,unverifiedCount:0,disprovenCount:0,publicationEligibleCount:0,malformedRecordCount:0,unsafeInputFieldCount:0; reasons=no-evidence,publication-ineligible; malformed=none; presence=deliveryId:y,reviewOutputKey:y,upstreamCorrelationKey:y,policyCorrelationKey:y; handoffOwner=available; redaction=privateOnly:y,rawPayloads:n,publicationFields:n,evidencePayloads:n,githubCommentBody:n,reducerRawPayload:n,discardedRawPayload:n,discardedPublicationFields:n,discardedEvidencePayloads:n

  • Review finding lifecycle: status=normalized; counts=input:1,recorded:1,rejected:0,unsafeInputFields:0; correlation=repo:y,pull:y,reviewOutputKey:y,deliveryId:y,commit:y; statuses=detected:1,open:1,suggested:0,validated:0,revalidated:0,resolved:0,blocked:0,degraded:0; severity=critical:0,major:1,medium:0,minor:0; actionability=actionable:0,needs-human-review:1,needs-reproduction:0,blocked:0,not-actionable:0; reasons=automatic-detected,automatic-open,automatic-review; rejected=none; redaction=privateOnly:y,rawPrompts:n,rawModelOutput:n,candidateBodies:n,toolPayloads:n,secretLike:n,diffs:n,unboundedArrays:n,unsafeFields:0

  • Review validation truth: status=normalized; counts=detected:1,suggested:0,validated:0,revalidated:0,resolved:0,blocked:0,degraded:0,open:1,uncertain:0,inputFindings:1,unsafeInputFields:0; evidence=fresh:0,stale:0,missingValidation:1,missingRevalidation:1; reasons=validation-missing:1; refs=rfl-f19a3a7fe34e34cb:open:validation-missing:fix:n:validation:n:revalidation:n; correlation=reviewOutputKey:y,deliveryId:y; redaction=privateOnly:y,rawPrompts:n,rawModelOutput:n,candidateBodies:n,replacementText:n,toolPayloads:n,secretLike:n,diffs:n,unboundedArrays:n,unsafeFields:0

  • Files reviewed: 1

  • Findings: 0 critical, 0 major, 0 medium, 0 minor

  • Lines changed: +18 -6

  • Profile: strict (auto, lines changed: 24)

  • Contributor experience: coarse-fallback (using coarse fallback signals only)

  • Shadow specialist: lane=docs-config-truth status=skipped reason=no-operator-truth-paths candidateCount=0 decisionCount=0 decisionCounts=candidate:0,duplicate:0,disagreement:0,dismissed:0,unclassifiable:0 duplicateCount=0 disagreementCount=0 dismissedCount=0 unclassifiableCount=0 truncatedCandidateCount=0 metricAvailability=token:n,cost:n,latency:n visiblePublicationDenied=true approvalPublicationDenied=true privateOnly=true shadowOnly=true redacted=raw:n,publication:n,approval:n,unsafe:0 correlationKey=2799440bf9b6e848 deliveryId=47694cc0-7241-11f1-8532-8a2d327… reviewOutputKey=kodiai-review-output:v1:inst-10…

  • Review completed: 2026-06-27T16:07:12.606Z

  • Total wall-clock: 6m 59s

  • Phase timings:

    • queue wait: 1ms
    • workspace preparation: 806ms
    • retrieval/context assembly: 3.2s
    • executor handoff: 53s
    • remote runtime: 5m 58s
    • publication: 2.4s
  • Tokens: 100 in / 15,405 out | 0.4389

  • Keyword parsing: No keywords detected

  • Budget behavior: complete (within-budget).

  • Prompt budget: 5 sections, 0 trimmed, 0 bypassed, 0 trimmed tokens.

  • Cache behavior: 2 observations, 1 hits, 1 misses, 0 degraded, 0 bypassed.

  • Continuation behavior: 0 observations, 0 compacted, 0 fallback, 0 degraded, 0 bypassed.

@CastagnaIT

CastagnaIT commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Unfortunately here you fix one thing but are breaking the previous attempt to make work the other video
the mentioned commit try to fix sample stream provided from issue #2010
you can download the sample stream, and test it by using a local http server

I’m not saying that mentioned commit was right, because i’m not expert on TS demuxer
but i expect a solution that make work them all

side note: we works on master branch "Piers", not Omega
backports only when on "Piers" the PR has been accepted

@wmdebrito

Copy link
Copy Markdown
Author

Unfortunately here you fix one thing but are breaking the previous attempt to make work the other video the mentioned commit try to fix sample stream provided from issue #2010 you can download the sample stream, and test it by using a local http server

I’m not saying that mentioned commit was right, because i’m not expert on TS demuxer but i expect a solution that make work them all

side note: we works on master branch "Piers", not Omega backports only when on "Piers" the PR has been accepted

Understood. I will try to fix the other issue you mentioned.

For piers I will install that version to test it. Right now I am using librelec 12.2 which runs Omega.

Thank you

@wmdebrito

Copy link
Copy Markdown
Author

Unfortunately here you fix one thing but are breaking the previous attempt to make work the other video the mentioned commit try to fix sample stream provided from issue #2010 you can download the sample stream, and test it by using a local http server

I’m not saying that mentioned commit was right, because i’m not expert on TS demuxer but i expect a solution that make work them all

side note: we works on master branch "Piers", not Omega backports only when on "Piers" the PR has been accepted

Create the PR: #2084

@wmdebrito wmdebrito closed this Jun 27, 2026
@wmdebrito wmdebrito changed the title [mpegts] Only auto-register PAT PIDs and validate the PSI section header - PlutoTv fails on ads for AI 21.5.21.1 [mpegts] Only auto-register PAT PIDs and validate the PSI section header - PlutoTv fails on ads for 21.5.21.1 Jun 27, 2026
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