Skip to content

Fix HEVC TS extra data construction for 3-byte start codes#2057

Merged
CastagnaIT merged 1 commit into
xbmc:Piersfrom
kontell:fix/hevc-ts-extradata
Jun 17, 2026
Merged

Fix HEVC TS extra data construction for 3-byte start codes#2057
CastagnaIT merged 1 commit into
xbmc:Piersfrom
kontell:fix/hevc-ts-extradata

Conversation

@kontell

@kontell kontell commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Description

The VPS/SPS/PPS copy assumed 4-byte start codes on both ends, so with 3-byte start codes it prepended a stray byte (extra data misdetected as hvcC) and truncated the NAL's last byte (corrupt PPS). Emit a clean Annex-B start code and copy only the NAL, mirroring the H.264 path.

Motivation and context

Playback of 4k HEVC streams is failing with inputstream.adaptive while working with inputstream.ffmpegdirect.

This is a demuxer bug, independent of and complementary to xbmc/xbmc#28103. #28103 fixes Kodi's VAAPI path allocating 8-bit (NV12) surfaces for 10-bit HEVC; this fixes the invalid HEVC extra data emitted by the MPEG-TS demuxer. Software decoding plays on both platforms - it's the hardware paths that fail, for different reasons:

  • Android (MediaCodec): the invalid extra data is fatal - CBitstreamConverter mis-detects it as hvcC and can't convert.
  • Linux (VAAPI): this fix clears the extra-data parse error, but #28103 is still needed for the 10-bit surface (error 18).
[Android / MediaCodec — invalid extra data is fatal here]
2026-06-15 13:08:12.407 T:12836 error <general>: CBitstreamConverter::Convert: error converting.
2026-06-15 13:08:12.407 T:12836 debug <general>: CDVDVideoCodecAndroidMediaCodec::AddData: waiting for keyframe (bitstream)
2026-06-15 13:08:12.418 T:12836 debug <general>: CDVDVideoCodecAndroidMediaCodec::AddData current state (2)

[Linux / ffmpeg — the invalid extra data this PR fixes]
2026-06-15 13:27:42.562 T:1837798 error <general>: ffmpeg[0x55c873bf0880]: [hevc] log2_parallel_merge_level_minus2 out of range: -1

[Linux / VAAPI — separate 10-bit surface fault, fixed by xbmc/xbmc#28103]
2026-06-15 13:18:24.888 T:1836092 error <general>: ffmpeg[0x55c8734a6be0]: [hevc] Failed to end picture decode issue: 18 (invalid parameter).
2026-06-15 13:18:24.888 T:1836092 error <general>: ffmpeg[0x55c8734a6be0]: [hevc] hardware accelerator failed to decode picture
2026-06-15 13:18:24.888 T:1836092 error <general>: GetPicture - avcodec_receive_frame returned failure

How has this been tested?

A test build for Android V22 was created and playback is now successful.

On Linux, without PR28103, the parallel_merge error is removed but playback still fails.

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

@kodiai

kodiai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Decision: APPROVE

Issues: none

Evidence:

  • Review prompt covered 2 changed files.
Review Details
  • Review plan: ready hash=32fc35de8979 route=standard task=review.full files=2 lines=82(local-diff) budget=na/759s 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=2057 key=kodiai-review-output:v1:inst-109141824:xbmc-inputstream.adaptive:pr-2057:action- delivery=4245da80-68cb-11f1-8ab2-aaf9e5f9eb1b

  • 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:724bdd2998443d4a5c058003980e2c9c; recordKey=candidate-publication-record:724bdd2998443d4a5c058003980e2c9c; correlationKey=candidate-publication-bridge:0795c19788339fa02320215250a37ad0; source=review-handler-publication; candidateRef=candidate-publication-summary-fc340c0a; 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-aaf490d666de13a6: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: 2

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

  • Lines changed: +41 -41

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

  • Contributor experience: profile-backed (using linked contributor profile guidance)

  • 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=669bd02a4d4d9ad6 deliveryId=4245da80-68cb-11f1-8ab2-aaf9e5f… reviewOutputKey=kodiai-review-output:v1:inst-10…

  • Review completed: 2026-06-15T15:11:36.256Z

  • Total wall-clock: 8m 53s

  • Phase timings:

    • queue wait: 0ms
    • workspace preparation: 1.3s
    • retrieval/context assembly: 5.2s
    • executor handoff: 33s
    • remote runtime: 8m 7s
    • publication: 3.3s
  • Tokens: 178 in / 24,565 out | 0.7275

  • 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.

@kontell kontell marked this pull request as ready for review June 16, 2026 11:10

@CastagnaIT CastagnaIT left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for the fix
please address the code comments

Comment thread lib/mpegts/mpegts/ES_hevc.cpp Outdated
Comment thread lib/mpegts/mpegts/ES_hevc.cpp Outdated
Comment thread lib/mpegts/mpegts/ES_hevc.cpp Outdated
Comment thread lib/mpegts/mpegts/ES_hevc.cpp Outdated
@CastagnaIT CastagnaIT added Type: Fix non-breaking change which fixes an issue v22 Piers labels Jun 16, 2026
The VPS/SPS/PPS copy assumed 4-byte start codes on both ends, so with
3-byte start codes it prepended a stray byte (extra data misdetected as
hvcC) and truncated the NAL's last byte (corrupt PPS). Emit a clean
Annex-B start code and copy only the NAL, mirroring the H.264 path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kontell kontell force-pushed the fix/hevc-ts-extradata branch from 98634c2 to ca06c19 Compare June 17, 2026 10:57
@kontell

kontell commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the comments, those four have been addressed with the latest push.

@CastagnaIT

Copy link
Copy Markdown
Collaborator

@kodiai review

@kodiai

kodiai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Decision: APPROVE

Issues: none

Evidence:

  • Review prompt covered 2 changed files.
  • Repo inspection tools were used to verify the changed code.
  • Review finding lifecycle: status=normalized; counts=input:0,recorded:0,rejected:0,unsafeInputFields:0; statuses=detected:0,open:0,validated:0,degraded:0; severity=critical:0,major:0,medium:0,minor:0; actionability=actionable:0,needs-human-review:0,blocked:0; rejected=none; redaction=privateOnly:y,rawPrompts:n,rawModelOutput:n,candidateBodies:n,toolPayloads:n,secretLike:n,diffs:n,unboundedArrays:n,unsafeFields:0

@CastagnaIT CastagnaIT merged commit a93c804 into xbmc:Piers Jun 17, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Fix non-breaking change which fixes an issue v22 Piers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants