-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Close JPEG-XL decoding/screenshot support, #3852 #4367
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
Conversation
|
I marked this PR as a draft because taking a JPEG XL screenshot while playing a HDR video did did not generate a screenshot that matched the video. Also there is a second issue in that with To test JPEG XL I played a downloaded copy of the YouTube video The World in HDR in 4K (ULTRA HD) using IINA+ build 170 and took a screenshot. I then repeated this with IINA I tested IINA with the changes in this PR applied to the changes in branch The screenshot generated by IINA+ uses this color space: When displayed in IINA or IINA+ that screenshot displays in HDR and looks like the video. The screenshot generated by IINA uses this color space: When viewed in IINA or IINA+ that screenshot is not displayed in HDR and is washed out. Full IINA+ Screenshot Info:low-batt@gag Screenshots$ ls -la The\ World\ in\ HDR\ in\ 4K\ \(ULTRA\ HD\)-0001.jxl
-rw-r--r--@ 1 low-batt staff 456600 Apr 19 19:17 The World in HDR in 4K (ULTRA HD)-0001.jxl
low-batt@gag Screenshots$ jxlinfo -v The\ World\ in\ HDR\ in\ 4K\ \(ULTRA\ HD\)-0001.jxl
JPEG XL image, 3840x2160, lossy, 16-bit RGB
num_color_channels: 3
num_extra_channels: 0
intensity_target: 10000.000000 nits
min_nits: 0.000000
relative_to_max_display: 0
linear_below: 0.000000
have_preview: 0
have_animation: 0
Intrinsic dimensions: 3840x2160
Orientation: 1 (Normal)
Color space: RGB, D65, Rec.2100 primaries, PQ transfer function, rendering intent: Relative
low-batt@gag Screenshots$ Full IINA Screenshot Info:@CarterLi Any guess as to the cause of the difference between IINA and IINA+? IINA+ was built with mpv master whereas IINA is using the mpv 0.35.1 release, so a difference in mpv is one possibility. |
|
HELP!! I'm requesting help on this one as I lack experience in this area. @CarterLi, I'm hoping for some advice on the HDR aspects. First, on the issue with mpv 0.35.1 and JPEG XL screenshots of HDR videos. I believe that is due to the mpv issue mpv-player/mpv#10988. The one line fix for that issue was merged right after the 0.35.1 release was cut. I will prepare a patch to mpv for that issue. With a working mpv and the screenshot format set to JPEG XL you can take a screenshot of a HDR video that looks like the video when viewed using IINA. The screenshot preview looks like EDR is working, but I'm unsure if the presentation is fully correct. What could be improved is the screenshot preview you see for a HDR video if HDR is turned off. It is clipped instead of tone mapped. Anyone know how to fix that? I was unable to get FFmpeg to generate what I believe is the bitmap format required by Apple. I added a workaround for that. Is there another approach I should be using? I included support for the display P3 color spaces, following what VideoView does, but I was unable to find a video that tests that. Anyway, this PR could use an intense mean detailed critical review. |
|
If I were you, I would use MPV (VideoView) to display the image, so that I could reuse most of the existing code, and would not have HDR issues. |
|
An interesting idea. I initially discounted using mpv due to issues with integrating with the OSD and the heavy overhead of dealing with a mpv core. I will give it more thought, however I believe it is going to be even harder to get that to work in the other use case which I did not mention. The other HDR issue we have not addressed is thumbnails for HDR videos. We could generate JPEG XL thumbnails that would show HDR thumbnails. The thumbnails all live in one file in a proprietary IINA format. Not sure how we could get mpv to read that. I suppose we could generate a video whose frames are the thumbnails. Something like that maybe. I will think on this. |
|
I played around with FFmpeg today from the command line and was able to generate from a 10 minute video at tiny video with only 65 frames, all of them keyframes. Something like that should allow us to use mpv for displaying HDR thumbnails. One reason I was focused on creating a NSPasteboard.general.writeObjects([image])If we use mpv to read the screenshot, we'd need a way to put the decoded screenshot into the pasteboard. I still need to figure that out. The case for using mpv is that this is the best way to ensure that these images match the video. That is a really compelling argument. To do this cleanly is going to require a lot of refactoring. It would be inappropriate to use
I have a some other issues I need to turn my attention to at the moment, but when I have time I will hack up an ugly test that uses mpv to make sure there isn't some sort of blocker to this plan. I'm thinking for now we continue to review this PR with the understanding that it is temporary code likely to be replaced later. |
iina/FFmpegController.h
Outdated
| /// - Parameter url: The URL identifying the image. | ||
| /// - Returns: An initialized NSImage object or null if the method cannot create an image representation from the contents of the | ||
| /// specified URL. | ||
| + (nullable NSImage *)createNSImageWithContentsOf:(nonnull NSURL *)url; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| + (nullable NSImage *)createNSImageWithContentsOf:(nonnull NSURL *)url; | |
| + (nullable NSImage *)createNSImageWithContentsOfURL:(nonnull NSURL *)url; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. I was trying to pattern this after this NSImage initializer. But I could not get the Swift name translation to use contentsOf for the parameter name. I had to add "With".
iina/FFmpegController.m
Outdated
| #import "IINA-Swift.h" | ||
|
|
||
| #define ERROR(msg, ...) [FFmpegLogger error:([NSString stringWithFormat:(msg), ##__VA_ARGS__])]; | ||
| #define LOG(msg, ...) [FFmpegLogger debug:([NSString stringWithFormat:(msg), ##__VA_ARGS__])]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call this INFO or similar personally, "LOG" isn't really a log level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem was the correct name would be DEBUG and that name is taken. I added a LOG_ prefix to these to allow uniform naming.
iina/FFmpegController.m
Outdated
| #if DEBUG | ||
| LOG(@"Creating image with contents of file: %s", cFilename) | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider moving this up so the strdup/free pair are closer together. I think technically the copy isn't required anyways
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I patterned this after getPeeksForFile figuring it must be correct, however using fileSystemRepresentation directly works fine.
| } | ||
| return image; | ||
| } | ||
| @finally { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this try-finally pattern was better than trying to cleanup in each of those error returns. If this was Swift I'd use defer after each allocation.
This commit will: - Remove ppm, pgm, pgmyuv and tga from the Preferences.ScreenshotFormat enum - Add webp and jxl to the Preferences.ScreenshotFormat enum - Add WebP (.webp) and JPEG XL (.jxl) as choices for the Forma` setting in the Screenshots section of General settings NOTE that removing enumeration cases breaks backward compatibility as the new cases reuse the tag values previously assigned to ppm and pgm. These four screenshot formats were dropped by mpv and removed from IINA's setting panel back in 2017. Anyone using these old formats would have had to update their settings therefore it should be acceptable to reuse the tag values. The main author of these changes is Carter Li. This is a merge of changes that have been tested in his IINA fork. Co-authored-by: CarterLi <carter.li@eoitek.com>
This commit will: - Remove ppm, pgm, pgmyuv and tga from the Preferences.ScreenshotFormat enum - Add webp and jxl to the Preferences.ScreenshotFormat enum - Add WebP (.webp) and JPEG XL (.jxl) as choices for the Format setting in the Screenshots section of General settings - Add a new method createNSImageWithContentsOf to FFmpegController - Add a new private method createImage to PlayerCore that will call the createNSImageWithContentsOf method if the normal NSImage initializer is unable to decode the screenshot - Change PlayerCore.screenshotCallback to use the new method to create a NSImage to preview in the OSD - Add a new class FFmpegLogger that provides access to the normal IINA logger to the FFmpegController - Change the FFmpegController to use the IINA logger instead of NSLog when logging messages - Add an internal setting enableFFmpegImageDecoder to allow disabling use of the FFmpeg image decoder should a problem be uncovered - Change the screenshot preview animation duration to adhere to accessibility settings NOTE that removing enumeration cases breaks backward compatibility as the new cases reuse the tag values previously assigned to ppm and pgm. These four screenshot formats were dropped by mpv and removed from IINA's setting panel back in 2017. Anyone using these old formats would have had to update their settings therefore it should be acceptable to reuse the tag values. The main author of the settings changes is Carter Li. That portion of the PR is a merge of changes that have been tested in his IINA fork. The FFmpeg related changes are new and support the ability to show screenshot previews in the OSD for image formats not supported by AppKit. Currently JPEG XL is not supported by the NSImage initializer. This is also true for WebP in macOS versions before Big Sur. Co-authored-by: CarterLi <carter.li@eoitek.com>
This commit will: - Remove ppm, pgm, pgmyuv and tga from the Preferences.ScreenshotFormat enum - Add webp and jxl to the Preferences.ScreenshotFormat enum - Add WebP (.webp) and JPEG XL (.jxl) as choices for the Format setting in the Screenshots section of General settings - Add a new method createNSImageWithContentsOfURL to FFmpegController - Add a new private method createImage to PlayerCore that will call the createNSImageWithContentsOfURL method if the normal NSImage initializer is unable to decode the screenshot - Change PlayerCore.screenshotCallback to use the new method to create a NSImage to preview in the OSD - Add a new class FFmpegLogger that provides access to the normal IINA logger to the FFmpegController - Change the FFmpegController to use the IINA logger instead of NSLog when logging messages NOTE that removing enumeration cases breaks backward compatibility as the new cases reuse the tag values previously assigned to ppm and pgm. These four screenshot formats were dropped by mpv and removed from IINA's setting panel back in 2017. Anyone using these old formats would have had to update their settings therefore it should be acceptable to reuse the tag values. The main author of the settings changes is Carter Li. That portion of the PR is a merge of changes that have been tested in his IINA fork. The FFmpeg related changes are new and support the ability to show screenshot previews in the OSD for image formats not supported by AppKit. Currently JPEG XL is not supported by the NSImage initializer. This is also true for WebP in macOS versions before Big Sur. Co-authored-by: CarterLi <carter.li@eoitek.com>
|
Rebased with |
Why not enum ScreenshotFormat: Int, InitializingFromKey {
case png = 0
case jpg
case jpeg
case webp = 7
case jxl
} |
|
Back when this was first coded we decided that as these settings had been all dropped back in 2017 it was very unlikely that reusing the values would be a problem. If we want to avoid reusing then we can change the enum like shown. We'd also have to override the normal tag values in the XIB for the pull down menu items so the tags match up with the enum values. All very doable. Should I make that change? |
|
OK, it should be fine. If we also need to change the XIB then it's probably not worth the hassle. |
This commit will:
ppm,pgm,pgmyuvandtgafrom thePreferences.ScreenshotFormatenumwebpandjxlto thePreferences.ScreenshotFormatenumWebP (.webp)andJPEG XL (.jxl)as choices for theFormatsetting in theScreenshotssection ofGeneralsettingsNOTE that removing enumeration cases breaks backward compatibility as the new cases reuse the tag values previously assigned to
ppmandpgm. These four screenshot formats were dropped by mpv and removed from IINA's setting panel back in 2017. Anyone using these old formats would have had to update their settings therefore it should be acceptable to reuse the tag values.The main author of these changes is Carter Li. This is a merge of changes that have been tested in his IINA fork.
Description: