libheif
libheif copied to clipboard
Is it possible to add the option to convert 8bit input to 10bit encoding for heif-enc?
The --depth of avifenc enables it, can heif-enc add a similar option? Thanks.
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?
@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.
Metrics?
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...
I think you need to measure it.
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
Update: It doesn't seem right for me to use -b, sorry I'm sleepy now.
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
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.
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
You can also use the --benchmark option.
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
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
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.
For me color related just implementing avifenc-like
-dand-yis 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.
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.
Would like to add something like
-p depth=10if 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.
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.
Hi, just to help clarify sommio’s point:
Currently, the --bit-depth option only affects the output when the input image is a 16-bit PNG, as stated in the help message:
-b, --bit-depth bit-depth of generated HEIF/AVIF file when using 16-bit PNG input (default: 10 bit)
What sommio is requesting is for the --bit-depth option to be extended to apply regardless of the input bit depth — whether the input is 8-bit, 10-bit, or 16-bit (PNG, JPEG, etc). This way, users could upscale 8-bit images to 10-bit encoded HEIF/AVIF outputs, which is a common practice to reduce banding and improve visual quality during compression, even if the source image itself is lower precision.