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

Is it possible to add the option to convert 8bit input to 10bit encoding for heif-enc? #1163

Open
sommio opened this issue Apr 13, 2024 · 17 comments

Comments

@sommio
Copy link

sommio commented Apr 13, 2024

The --depth of avifenc enables it, can heif-enc add a similar option? Thanks.

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

There is a similar option: --bit-depth. However it is intended for 16 bit input which is a PNG capability, so while it would be worth a try, you may need to preprocess your data.

I am curious why this is needed though. What are you trying to do?

@sommio
Copy link
Author

sommio commented Apr 13, 2024

@bradh Thanks for the quick reply, since places like doom9.org and r/av1 say that even if the source is 8bit converted to 10bit encoding it will be better, so I've been doing that.

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

Metrics?

@sommio
Copy link
Author

sommio commented Apr 13, 2024

eg. https://web.archive.org/web/20221026170800/x264.nl/x264/10bit_02-ateme-why_does_10bit_save_bandwidth.pdf ?

https://forum.doom9.org/showthread.php?t=155510

I haven't found easy to understand data and I can't make sense of it. But the people who say it look like they have a lot of authority...

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

I think you need to measure it.

@sommio
Copy link
Author

sommio commented Apr 13, 2024

It does achieve better compression

❯ ffmpeg -i in.png -pix_fmt rgb48le in16.png
❯ heif-enc -p chroma=444 -p x265:crf=18 -b 8 in16.png out8.heic
❯ heif-enc -p chroma=444 -p x265:crf=18 -b 10 in16.png out10.heic
.rw-r--r-- 2.1M sommio 13 Apr 09:22 in.png
.rw-r--r-- 5.4M sommio 13 Apr 11:03 in16.png
.rw-r--r-- 190k sommio 13 Apr 11:08 out8.heic
.rw-r--r-- 171k sommio 13 Apr 11:08 out10.heic

sample.zip

Update: It doesn't seem right for me to use -b, sorry I'm sleepy now.

@sommio
Copy link
Author

sommio commented Apr 13, 2024

When I tried crf=23, 10bit clearly produced smoother colours relative to 8bit, although not perfect.

❯ heif-enc -p chroma=444 -p x265:crf=23 in.png out.heic
❯ heif-enc -p chroma=444 -p x265:crf=23 in16.png out10.heic

samples.zip

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

Interesting. What do the ssim and psnr show?

In any case it might help to provide more detail on what feature you still need added to meet your functionality needs.

@sommio
Copy link
Author

sommio commented Apr 13, 2024

CRF=23 heic, converted to png by heif-convert for testing.

❯ ffmpeg -i in.png -i out.heic.png -lavfi psnr=stats_file=psnr_logfile.txt -f null -
PSNR r:41.265603 g:44.702212 b:40.099869 average:41.625919 min:41.625919 max:41.625919
❯ ffmpeg -i in.png -i out10.heic.png -lavfi psnr=stats_file=psnr_logfile.txt -f null -
PSNR r:41.545412 g:44.980944 b:40.299449 average:41.867365 min:41.867365 max:41.867365


❯ ffmpeg -i in.png -i out.heic.png  -lavfi ssim=stats_file=ssim_logfile.txt -f null -
SSIM R:0.976770 (16.339568) G:0.985796 (18.475935) B:0.971941 (15.519297) All:0.978169 (16.609302)
❯ ffmpeg -i in.png -i out10.heic.png  -lavfi ssim=stats_file=ssim_logfile.txt -f null -
SSIM R:0.978460 (16.667583) G:0.986987 (18.856298) B:0.973736 (15.806391) All:0.979728 (16.930992)

❯ ffmpeg -i in.png -i out.heic.png -lavfi libvmaf="/usr/share/model/vmaf_v0.6.1neg.json":log_path=vmaf_logfile.txt -f null -
VMAF score: 96.999291
❯ ffmpeg -i in.png -i out10.heic.png -lavfi libvmaf="/usr/share/model/vmaf_v0.6.1neg.json":log_path=vmaf_logfile.txt -f null -
VMAF score: 97.004798

❯ ssimulacra2_rs image in.png out.heic.png
Score: 83.79216415
❯ ssimulacra2_rs image in.png out10.heic.png
Score: 85.60857730

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

You can also use the --benchmark option.

@sommio
Copy link
Author

sommio commented Apr 13, 2024

It seems to support only YCbCr image.

❯ heif-enc --benchmark -p chroma=444 -p x265:crf=18 in.png
Benchmark can only be computed on YCbCr or monochrome images
PSNR: 0.00 time: 0.8 size: 176563

@sommio
Copy link
Author

sommio commented Apr 13, 2024

For me color related just implementing avifenc-like -d and -y is enough.

The others I would like to be able to use all svtav1 parameters, which I haven't tried yet.

    -d,--depth D                      : Output depth [8,10,12]. (JPEG/PNG only; For y4m or stdin, depth is retained)
    -y,--yuv FORMAT                   : Output format [default=auto, 444, 422, 420, 400]. Ignored for y4m or stdin (y4m format is retained)
                                        For JPEG, auto honors the JPEG's internal format, if possible. For all other cases, auto defaults to 444

@silverbacknet
Copy link

10-bit does prevent/minimize visible banding on smooth gradients, especially colors closer to black and white (where YUV is narrowest). It generally doesn't show up on metrics, since they mainly measure gross distortion, not something as fine as +/-1 banding.

If the banding is in the source, or if the quality is high enough that nothing is smoothed out, it won't matter. There are a lot of times it can work out well for heavier compression though, even without an initial 10+ pipeline, since all of the rounding is then inside the 10-bit.

With H.264 it had actual coding efficiency gains as well, with HEVC and AV1 it generally does not, only the banding prevention.

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

For me color related just implementing avifenc-like -d and -y is enough.

    -d,--depth D                      : Output depth [8,10,12]. (JPEG/PNG only; For y4m or stdin, depth is retained)
    -y,--yuv FORMAT                   : Output format [default=auto, 444, 422, 420, 400]. Ignored for y4m or stdin (y4m format is retained)
                                        For JPEG, auto honors the JPEG's internal format, if possible. For all other cases, auto defaults to 444

I think those are already available in some form. What specially doesn't work for you?

Clearly heif-enc and avifenc are not the same, and will not have identical functionality.

@sommio
Copy link
Author

sommio commented Apr 13, 2024

Yes, heif-enc can use -p chroma=444 instead of -y.
But I would also like heif-enc to be able to do the 8bit to 10bit conversion to output a 10bit image.
Now I need to preprocess it using ffmpeg.

Would like to add something like -p depth=10 if possible, thanks.

@bradh
Copy link
Contributor

bradh commented Apr 13, 2024

Would like to add something like -p depth=10 if possible, thanks.

We already have --bit-depth / -b. So what (exactly) do you need that those do not do?

I can guess, but it really is better if you make a single, complete statement of exactly what does work the way you want, and what does not, and how it should work instead. The details really do matter - PNG, JPEG, etc, exactly which bit depths, etc.

@sommio
Copy link
Author

sommio commented Apr 14, 2024

I need --bit-depth to work not only for 16bit png, but also want it to work for 8bit png/jpeg etc.
I want any 8bit input to output a 10bit heic/avif.
I'm sorry if what I said was confusing to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants