[video_player] Fix washed-out HDR video playback on iOS#11569
Open
StefanGilligan wants to merge 1 commit intoflutter:mainfrom
Open
[video_player] Fix washed-out HDR video playback on iOS#11569StefanGilligan wants to merge 1 commit intoflutter:mainfrom
StefanGilligan wants to merge 1 commit intoflutter:mainfrom
Conversation
AVPlayerItemVideoOutput was being constructed with only pixel buffer attributes and no AVVideoColorPropertiesKey. For HDR sources (HLG, PQ, Dolby Vision) AVFoundation then hands the decoder's BT.2020 samples through to the Flutter texture unconverted, which samples them as sRGB. The result is washed-out highlights, raised blacks, and desaturated midtones. Switch to -initWithOutputSettings: and declare BT.709 color properties on the output. AVFoundation's pixel transfer session now tone-maps and gamut-converts HDR into BT.709 SDR on the way into the pixel buffer, at no per-frame CPU cost. For SDR (BT.709) sources this is a no-op. AVVideoColorPropertiesKey must live in the output settings dictionary passed to -initWithOutputSettings:. Color keys placed under the pixel buffer attributes dictionary are silently ignored by AVFoundation; this is the trap that has kept the underlying issue unresolved. See WWDC22 "Display HDR video in EDR with AVFoundation and Metal" and Apple Developer Forum thread 686044 for the prescribed approach. Addresses flutter/flutter#91241 and flutter/flutter#143080.
There was a problem hiding this comment.
Code Review
This pull request updates the video_player_avfoundation package to version 2.9.5. It addresses an issue where HDR video playback appeared washed out on iOS by configuring the AVPlayerItemVideoOutput with BT.709 color properties, forcing tone-mapping to SDR. The changes include updating the FVPAVFactory interface and implementation to support general output settings instead of just pixel buffer attributes, and adding a unit test to verify the configuration. I have no feedback to provide.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Declares BT.709 color properties on
AVPlayerItemVideoOutputso AVFoundation tone-maps HDR sources (HLG, PQ, Dolby Vision) into the Flutter texture on the way into the pixel buffer.Previously the output was constructed with only pixel buffer attributes, so HDR BT.2020 samples reached the Flutter texture unconverted, were sampled as sRGB, and produced washed-out highlights, raised blacks, and desaturated midtones. SDR (BT.709) sources are unaffected (BT.709 → BT.709 is a no-op).
The canonical fix per Apple is to construct the output with
-initWithOutputSettings:and passAVVideoColorPropertiesKeywith a BT.709 triplet.AVVideoColorPropertiesKeyplaced underpixelBufferAttributesis silently ignored — this is the trap that has kept the underlying issue open for years.Internal factory method renamed from
videoOutputWithPixelBufferAttributes:tovideoOutputWithOutputSettings:to reflect that the dictionary is now output settings (which may still include pixel buffer attribute keys).References:
Fixes
Tested on
Manual validation against an iPhone camera roll containing HLG and Dolby Vision clips, played inside a Flutter app using
video_player. Before: preview washed out, highlights clipped grey, blacks raised. After: preview matches Photos.app for the same source clip. SDR BT.709 content renders identically to before.A unit test (
videoOutputIsConfiguredWithBT709ColorProperties) was added to assert the BT.709 triplet is present in theoutputSettingsdictionary passed to the factory — this locks in the fix against silent regression (since the oldpixelBufferAttributes-only path produced no test failure and no runtime error, just visually wrong output).Pre-Review Checklist
[shared_preferences]///).