Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 17 (from beta 7+) Force Decode on HEIF/AVIF image may crash #3604

Open
3 tasks done
joaopdcgarcia opened this issue Sep 18, 2023 · 18 comments
Open
3 tasks done

iOS 17 (from beta 7+) Force Decode on HEIF/AVIF image may crash #3604

joaopdcgarcia opened this issue Sep 18, 2023 · 18 comments
Labels
apple bug apple's bug cause our framework author's pain avif AV1 Image Format heif

Comments

@joaopdcgarcia
Copy link

joaopdcgarcia commented Sep 18, 2023

New Issue Checklist

Issue Info

Info Value
Platform Name ios
Platform Version 17.0 *but may be not exclusive
SDWebImage Version 5.18.0
Integration Method cocoapods
Xcode Version xcode 14.3.1
Repro rate can't reproduce

Issue Description and Steps

We are seeing two new issues that are very similar, since we have updated from 5.16.0. to 5.18.0. . In addition to .jpg and .png we also have recently added support for .webp (iOS 14 and iOS 15) and .avif (iOS 16 and above)

Screenshot 2023-09-18 at 4 17 36 PM

Screenshot 2023-09-18 at 4 18 35 PM

Screenshot 2023-09-18 at 4 18 49 PM

Any clues on what might be causing this?
Would you advise to downgrade to 5.16.0 before the issues started to happen? Or perhaps, if this is iOS 17, SDWebImage needs to catchup?

@dreampiggy dreampiggy added apple bug apple's bug cause our framework author's pain heif labels Sep 19, 2023
@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 19, 2023

Guess this is Apple HEIF/HEVC decoder issue. It seems like a OOM ?

If you want, you can disable the Force Decode, see that SDImageForceDecodePolicy, set into never instead ? So the decoding is happended during rendering (which means, CALayer's rendering part, viaCA::copy_image)

Or you can set the SDImageCoderHelper defaultDecodeSolution into CoreAnimation, which does not use UIImageGraphicsRenderer (But I don't think this has any differences, it still trigger the lazy CGImage's decoding, but with a different stack trace)

@dreampiggy
Copy link
Contributor

Does the similar stack trace only contains HEIFReadPlugin from Apple's ImageIO ?

Not something like AppleJPEGReadPlugin or PNGReadPlugin ? Seems HEIF/HEVC only issues about Apple's close-sourced HEIF decoder.

@dreampiggy
Copy link
Contributor

Wait a minute, why SDImageCoderHelper decodedImageForImage: trigger the GraphicsRenderer ?

It actually should use the UIImage prepareForDisplay, because it's supported by UIKit to use the faster force decode solution.

Did you change the DecodeSolution from automatic into coreAnimation ?

@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 19, 2023

image

Need a iOS 17 device (with A12+ chip) to test, is this magic test failed ? SDImageSupportsHardwareHEVCDecoder

@dreampiggy
Copy link
Contributor

Can you use the real iOS 17 device and debug with that HEIF image url ? Whether that SDImageSupportsHardwareHEVCDecoder or some other logic failed to into the SDImageDecodeUIKit call

@joaopdcgarcia
Copy link
Author

joaopdcgarcia commented Sep 19, 2023

Does the similar stack trace only contains HEIFReadPlugin from Apple's ImageIO ?

Both stack traces are in the issue I above.

Did you change the DecodeSolution from automatic into coreAnimation ?

We are not doing any configuration to SDWebImage other than this:

        SDWebImageDownloader.shared.setValue(
            "Bearer \(ImageDownloadManager.imageServerSecret)",
            forHTTPHeaderField: "Authorization")
        SDWebImagePrefetcher.shared.maxConcurrentPrefetchCount = 6
        SDImageCache.shared.config.diskCacheReadingOptions = NSData.ReadingOptions.mappedIfSafe
        SDImageCache.shared.config.maxMemoryCount = 40 // 40 Images in memory max
        SDImageCache.shared.config.maxDiskAge = 7884000 // Three months

Then use it as such:

        let options: SDWebImageOptions = highPriority == true
            ? [.continueInBackground, .highPriority, .forceTransition, .retryFailed]
            : [.continueInBackground, .forceTransition, .retryFailed]

        Tracker.trackDebugMessage("Image Management: Downloading from setImage " + urlToUse.absoluteString)
        sd_setImage(
            with: urlToUse,
            placeholderImage: placeholderImage,
            options: options,
            completed: { [weak self] image, error, _, imageURL in
            

Can you use the real iOS 17 device and debug with that HEIF image url ? Whether that SDImageSupportsHardwareHEVCDecoder or some other logic failed to into the SDImageDecodeUIKit call

I'll debug an AVIF download and let you know.

@joaopdcgarcia
Copy link
Author

joaopdcgarcia commented Sep 19, 2023

Screenshot 2023-09-19 at 10 40 25 AM
Screenshot 2023-09-19 at 10 40 44 AM
Screenshot 2023-09-19 at 10 40 51 AM
Screenshot 2023-09-19 at 10 43 49 AM

@dreampiggy
Copy link
Contributor

AVIF ? But your stacktrace shows Apple's ImageIO's HEIFReaderPlugin

@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 19, 2023

Oh, I see. HEIF standard does not require to use HEVC as codec. There are some HEIF with AV1 codec, called heif({ compression: 'av1' })....

Which means, Apple's HEIF plugin can decode some AVIF actually...But they does not always gurantee. So if you feed some HEVC encoded AVIF files into ImageIO, it will using the built-in decoder to decode, not the SDWebImageAVIFCoder (open-sourced)

@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 19, 2023

A stupid workaround is to add the open-sourced SDImageAVIFCoder, before that SDImageIOCoder (which has higher priority), so that those AVIF images does not passed into ImageIO but use source-codec libavif for decoding...

@dreampiggy dreampiggy added the avif AV1 Image Format label Sep 19, 2023
@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 19, 2023

To say, we need a better way to check: What [UIImage prepareForDisplay:] this format supported..I can remove the conditional check there, but this cause annoying runtime logging from CMPhoto.framework...For example, if you have PNG/TIFF decoded from ImageIO, feed this UIImage into prepareForDisplay: will cause something logging like

Error -17102 decompressing image -- possibly corrupt
Error -17102 decompressing image -- possibly corrupt
Error -17102 decompressing image -- possibly corrupt

See the original PR: #3365

@joaopdcgarcia
Copy link
Author

ok. we'll see if our release timing is compatible with your fix. Otherwise and we'll attempt the SDImageAVIFCoder.
Let me know if you need assistance testing out / debugging on iOS 17.

@dreampiggy
Copy link
Contributor

You can have a try by disable the force decode firstly. See my second comments.

Note disable force decode may slightly effect frame rate on huge scroll list (because now image needed to be decoded when rendering, means on main queue)

If you have a large list with animated images, you can filter that using context option(which is controlled by per-image-request, not a global option)

@dreampiggy dreampiggy mentioned this issue Sep 20, 2023
3 tasks
@dreampiggy dreampiggy changed the title EXC_BAD_ACCESS SDGraphicsImageRenderer iOS 17 (from beta 7+) Force Decode on HEIF/AVIF file has low ratio of crash Sep 20, 2023
@dreampiggy dreampiggy pinned this issue Sep 20, 2023
@dreampiggy dreampiggy changed the title iOS 17 (from beta 7+) Force Decode on HEIF/AVIF file has low ratio of crash iOS 17 (from beta 7+) Force Decode on HEIF/AVIF image may crash Sep 20, 2023
@dreampiggy
Copy link
Contributor

Seems Apple's ImageIO decoder bug, no known way currently to workaround.

A quick hack is to use SDWebImageHEIFCoder (open-sourced, provided by me and use libheif instead of ImageIO) for iOS 17+ if you really care about the crash ratio.

Or maybe need further information to reproduce the crash, for example, can some special HEIF/AVIF image files trigger that crash ? So that we can fire radar to Apple's ImageIO team

@joaopdcgarcia @magicfengg

@joaopdcgarcia
Copy link
Author

we are falling back to WEBP for now, will let you know if we are able to reproduce this using AVIF so that apple can fix it.

@dreampiggy
Copy link
Contributor

dreampiggy commented Sep 20, 2023

Can you provide some AVIF/HEIF which can trigger that crash ? Isn't this reproducible ?

Because iPhone has HEVC hardware codec (and on iPhone 15 has AV1 hardware codec), maybe this also related to some specified iPhone Model ?

Need further information to report to Apple

@joaopdcgarcia
Copy link
Author

joaopdcgarcia commented Sep 20, 2023

As far as model goes, it is not specific. Check the left pane (expanded below).
image

I tracked down an image that is showing to be successfully downloaded (in various sizes, depending on the device's width) in the breadcrumbs. Nevertheless, the crash is not reproducible on my iPhone 14. I'm asking team members with larger devices to attempt to reproduce it.

@dreampiggy
Copy link
Contributor

Can now conclude in a bug, normal HEIF loaded UIImage rendering on UIImageView may still cause crash.

https://stackoverflow.com/questions/77134949/uiimage-drawinrectblendmodealpha-occur-crash-in-ios-17-how-to-fix-that

@dreampiggy dreampiggy unpinned this issue Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apple bug apple's bug cause our framework author's pain avif AV1 Image Format heif
Projects
None yet
Development

No branches or pull requests

2 participants