[camera_avfoundation] Fixes crash when using ResolutionPreset.max with iPhone 17#11106
[camera_avfoundation] Fixes crash when using ResolutionPreset.max with iPhone 17#11106LouiseHsu wants to merge 12 commits intoflutter:mainfrom
Conversation
| // found in the LICENSE file. | ||
|
|
||
| @testable import camera_avfoundation | ||
| import UIKit |
There was a problem hiding this comment.
i needed to add this to compile
There was a problem hiding this comment.
Code Review
This pull request addresses a critical crash when using ResolutionPreset.max with newer iPhone models that output btp2 pixel format, which the Flutter engine cannot render. It also resolves an issue where ResolutionPreset.max could return a square resolution due to Centre Stage camera changes. The changes introduce filtering for unsupported pixel formats and non-4:3 aspect ratios, ensuring a stable and expected camera output. New test cases have been added to validate this behavior.
| } | ||
|
|
||
| /// Finds the highest available resolution in terms of pixel count for the given device. | ||
| /// Finds the highest available resolution 16:9 in terms of pixel count for the given device. |
There was a problem hiding this comment.
The comment states "Finds the highest available resolution 16:9", but the implementation filters for a 4:3 aspect ratio (is4x3 = abs(ratio - 4.0 / 3.0) < 0.05). Please update the comment to accurately reflect the 4:3 aspect ratio filtering.
| /// Finds the highest available resolution 16:9 in terms of pixel count for the given device. | |
| /// Finds the highest available resolution 4:3 in terms of pixel count for the given device. |
| // Apple's lossy compressed formats that Flutter Metal can't render. | ||
| let unsupportedSubTypes: [FourCharCode] = [ | ||
| 1_651_798_066 // Hex for 'btp2', or kCVPixelFormatType_96VersatileBayerPacked12 | ||
| ] |
There was a problem hiding this comment.
The unsupportedSubTypes array is currently defined inside the highestResolutionFormat function. While its scope is limited to this function, defining it as a static let constant outside the function would prevent its re-initialization on every call to highestResolutionFormat, improving minor efficiency and making it clear that these are globally unsupported types for the Flutter Metal renderer.
| // Apple's lossy compressed formats that Flutter Metal can't render. | |
| let unsupportedSubTypes: [FourCharCode] = [ | |
| 1_651_798_066 // Hex for 'btp2', or kCVPixelFormatType_96VersatileBayerPacked12 | |
| ] | |
| static let unsupportedSubTypes: [FourCharCode] = [ | |
| 1_651_798_066 // Hex for 'btp2', or kCVPixelFormatType_96VersatileBayerPacked12 | |
| ] | |
| // Apple's lossy compressed formats that Flutter Metal can't render. |
Fixes flutter/flutter#175828
The iPhone 17 family's new camera supports a new pixel format, btp2, which is a lossy, compressed format. At 12MP+ resolutions, AVFoundation drops support for standard YUV/BGRA and strictly outputs this format (e.g., 1651798066 / btp2). The engine renderer expects raw pixels and crashes immediately when given this compressed format. (relevant engine issue: flutter/flutter#182908)
Separately, Centre Stage was introduced for iPhone 17 which is a square sensor. A side effect of this is when we request the highest non-btp resolutions, we previously selected based off total number of pixels. This meant that it was returning a wonky 4032x4032 square. I added a check to only return 4:3 resolutions that aren't square like it did previously, just to avoid previous implementations looking weird.
Pre-Review Checklist
[shared_preferences]pubspec.yamlwith an appropriate new version according to the [pub versioning philosophy], or I have commented below to indicate which [version change exemption] this PR falls under[^1].CHANGELOG.mdto add a description of the change, [following repository CHANGELOG style], or I have commented below to indicate which [CHANGELOG exemption] this PR falls under[^1].///).