Open tuqueque opened 2 years ago
Hi tuqueque,
Thank you for the bug report. I don't use -a denoise-noise-level=
, so I will need detailed steps to reproduce how you build avifenc
and also aomenc
. In particular, how you check out the libavif and libaom source trees.
Please also post the output of your avifenc --version
command.
If you can still build an old version of avifenc
in which -a denoise-noise-level=16
works, that will also be very helpful.
Thanks.
I don't use
-a denoise-noise-level=
, so I will need detailed steps to reproduce
The exact command I run when I convert images with avifenc is:
avifenc --codec aom --ignore-icc --yuv 420 --depth 10 --speed 1 --min 1 --max 63 --minalpha 1 --maxalpha 63 -a end-usage=q -a cq-level=16 -a frame-boost=1 -a enable-keyframe-filtering=1 -a tune=ssim -a dist-metric=qm-psnr -a enable-qm=1 -a qm-min=1 -a qm-max=14 -a enable-chroma-deltaq=1 -a enable-dnl-denoising=0 -a denoise-noise-level=256 -a enable-ab-partitions=0 -a disable-trellis-quant=0 -a quant-b-adapt=1 -a enable-tpl-model=1 -a deltaq-mode=3 -a aq-mode=1 -a sharpness=1 input_image.png output_image.avif
how you build
avifenc
and alsoaomenc
. In particular, how you check out the libavif and libaom source trees.
I'm fairly new to building stuff from source, so I don't understand the question entirely, the one-liner version command I run to build avifenc is:
git clone https://github.com/AOMediaCodec/libavif.git && cd libavif && cd ext && ./aom.cmd && cd .. && cd .. && mkdir build && cd build && cmake /home/user/SourceBuilds/libavif -DCMAKE_BUILD_TYPE=Release -DAVIF_LOCAL_AOM=1 -DAVIF_CODEC_AOM=1 -DBUILD_SHARED_LIBS=0 -DAVIF_BUILD_APPS=1 && make
Please also post the output of your
avifenc --version
command.avifenc --version Version: 0.10.1 (aom [enc/dec]:3.5.0) libyuv : available (1813)
If you can still build an old version of
avifenc
in which-a denoise-noise-level=16
works, that will also be very helpful.
Yes, I managed to find the last version where the -a denoise-noise-level=16
command worked, the version is 0.9.3
Just one little detail in case you do some testing with the command I run when converting images in avifenc, with version 0.9.3 of avifenc, the parameter -a dist-metric=qm-psnr
will throw an error. I guess it wasn't implemented in that version yet, so just remove it when using 0.9.3.
Hi tuqueque,
Could you print the output of the avifenc --version
command in which -a denoise-noise-level=16
works?
If you still have the source tree for that avifenc
command, could you cd into the libavif directory and post the output of the git log -1
command?
Thanks.
Could you print the output of the avifenc --version command in which -a denoise-noise-level=16 works?
avifenc --version
Version: 0.9.3 (aom [enc/dec]:3.2.0)
libyuv : available (1813)
If you still have the source tree for that avifenc command, could you cd into the libavif directory and post the output of the git log -1 command?
Once again, I don't understand this question. I barely know git stuff. I mostly build stuff following what I find over Internet and try to understand the commands...
To build the 0.9.3 version of avifenc, I just downloaded the 0.9.3 sources from this very github site ( https://github.com/AOMediaCodec/libavif/archive/refs/tags/v0.9.3.zip ) and ran almost the same command as always, but "adapted" to the 0.9.3 folder:
cd libavif-0.9.3/ext && ./aom.cmd && cd .. && cd .. && mkdir build && cd build && cmake /home/user/SourceBuilds/libavif -DCMAKE_BUILD_TYPE=Release -DAVIF_LOCAL_AOM=1 -DAVIF_CODEC_AOM=1 -DBUILD_SHARED_LIBS=0 -DAVIF_BUILD_APPS=1 && make
The resulting libavif 0.9.3 binary seems to work as intended, so I think I'm doing it correctly... although probably not in the most elegant way.
Hi tuqueque,
Thank you. You've answered my questions about how you built both versions of avifenc
.
You also mentioned you used aomenc
. Did you build it from source code? Could you paste the last few lines of the output of aomenc --help
? It should look like the following:
Included encoders:
av1 - AOMedia Project AV1 Encoder 3.5.0-226-g6fb5c7eea (default)
Use --codec to switch to a non-default encoder.
You also said denoise-noise-level=16 still works in aomenc perfectly. What is the aomenc
command line you're using?
In the libaom v3.3.0 release notes, I found the following item:
It may be related to the problem you reported. I will ask my coworkers on the libaom team about this.
You also mentioned you used
aomenc
. Did you build it from source code?
Oh, yes, I forgot to answer that question... Yes, I build it from source, this is the command I use to build it:
git clone https://aomedia.googlesource.com/aom && mkdir aom_build && cd aom_build && cmake /home/user/SourceBuilds/aom -DCONFIG_TUNE_BUTTERAUGLI=1 -DCONFIG_THREE_PASS=1 -DCONFIG_FRAME_PARALLEL_ENCODE=1 && make
Could you paste the last few lines of the output of
aomenc --help
?
Included encoders:
av1 - AOMedia Project AV1 Encoder 3.5.0-242-g6ed0c7a32 (default)
Use --codec to switch to a non-default encoder.
You also said denoise-noise-level=16 still works in aomenc perfectly. What is the
aomenc
command line you're using?
Oh, boy... I use a VERY long string of commands involving ffmpeg piping the output to aomenc using 2-pass encoding and mkvmerge... the relevant portion of the command would be this:
--good --use-16bit-internal --end-usage=vbr --target-bitrate=512 --tile-columns=1 --tile-rows=0 --row-mt=1 --frame-parallel=1 --threads=4 --cpu-used=2 --min-q=1 --sb-size=64 --bit-depth=10 --lag-in-frames=48 --arnr-strength=0 --arnr-maxframes=0 --tune=ssim --dist-metric=qm-psnr --kf-min-dist=24 --kf-max-dist=1440 --sframe-dist=4096 --sframe-mode=1 --frame-boost=1 --enable-fwd-kf=1 --enable-keyframe-filtering=1 --enable-qm=1 --qm-min=1 --qm-max=14 --enable-chroma-deltaq=1 --enable-dnl-denoising=0 --denoise-noise-level=16 --enable-ab-partitions=0 --coeff-cost-upd-freq=1 --disable-trellis-quant=0 --quant-b-adapt=1 --enable-tpl-model=1 --deltaq-mode=3 --aq-mode=1 --sharpness=1 --webm -o FILE_OUTPUT
If you really want to see the full, insane string...
printf $RANDOM | xargs -i sh -c 'ffmpeg -i "INPUT_FILE" -ac 2 -vbr on -c:a libopus -compression_level 10 -frame_duration 60 -b:a 64k -y "{}_audio.opus" & ffmpeg -i "INPUT_FILE" -loglevel quiet -map 0:0 -an -sn -pix_fmt yuv420p -f yuv4mpegpipe - | aomenc --passes=2 --pass=1 --fpf={}_1stpass.log --two-pass-output={}_2ndpass.log --second-pass-log={}_2ndpass.log --good --use-16bit-internal --end-usage=vbr --target-bitrate=512 --tile-columns=1 --tile-rows=0 --row-mt=1 --frame-parallel=1 --threads=4 --cpu-used=2 --min-q=1 --sb-size=64 --bit-depth=10 --lag-in-frames=48 --arnr-strength=0 --arnr-maxframes=0 --tune=ssim --dist-metric=qm-psnr --kf-min-dist=24 --kf-max-dist=1440 --sframe-dist=4096 --sframe-mode=1 --frame-boost=1 --enable-fwd-kf=1 --enable-keyframe-filtering=1 --enable-qm=1 --qm-min=1 --qm-max=14 --enable-chroma-deltaq=1 --enable-dnl-denoising=0 --denoise-noise-level=16 --enable-ab-partitions=0 --coeff-cost-upd-freq=1 --disable-trellis-quant=0 --quant-b-adapt=1 --enable-tpl-model=1 --deltaq-mode=3 --aq-mode=1 --sharpness=1 --webm -o /dev/null - && ffmpeg -i "INPUT_FILE" -loglevel quiet -map 0:0 -an -sn -pix_fmt yuv420p -f yuv4mpegpipe - | aomenc --passes=2 --pass=2 --fpf={}_1stpass.log --two-pass-output={}_2ndpass.log --second-pass-log={}_2ndpass.log --good --use-16bit-internal --end-usage=vbr --target-bitrate=512 --tile-columns=1 --tile-rows=0 --row-mt=1 --frame-parallel=1 --threads=4 --cpu-used=2 --min-q=1 --sb-size=64 --bit-depth=10 --lag-in-frames=48 --arnr-strength=0 --arnr-maxframes=0 --tune=ssim --dist-metric=qm-psnr --kf-min-dist=24 --kf-max-dist=1440 --sframe-dist=4096 --sframe-mode=1 --frame-boost=1 --enable-fwd-kf=1 --enable-keyframe-filtering=1 --enable-qm=1 --qm-min=1 --qm-max=14 --enable-chroma-deltaq=1 --enable-dnl-denoising=0 --denoise-noise-level=16 --enable-ab-partitions=0 --coeff-cost-upd-freq=1 --disable-trellis-quant=0 --quant-b-adapt=1 --enable-tpl-model=1 --deltaq-mode=3 --aq-mode=1 --sharpness=1 --webm -o "{}_video.webm" - && mkvmerge -o "{}_2pass_speed2_kf24-1440_sf4096_b512.mkv" "/home/user/{}_video.webm" "/home/user/{}_audio.opus"
In the libaom v3.3.0 release notes, I found the following item:
* Auto select noise synthesis level for all intra
It may be related to the problem you reported. I will ask my coworkers on the libaom team about this.
Thanks! I really hope the film grain noise feature comes back to avifenc. It really is useful!
Hi tuqueque,
Thank you for the answers. I also found the libaom changelist "Auto select noise synthesis level for all intra":
https://aomedia-review.googlesource.com/c/aom/+/147641
The change at lines 3750-3766 in av1/encoder/encoder.c in the changelist can explain this bug. libavif uses the all intra mode of libaom to encode still images, and cpi->oxcf.noise_level
is the -a denoise-noise-level=
value you passed to avifenc
. The current code replaces the cpi->oxcf.noise_level
value that you specified with a synthetic value, and the synthetic value is capped at 5.0.
Huh, interesting... I hope you consider this a bug and not a feature in avifenc... I really think the user should be able to control/decide how much noise they want in an image. I don't like that the encoder decides what value to use.
Also, does this apply to aomenc as well?... Reading the description in the commit, it seems to only affect aomenc if the "--allintra" command is placed in conjuction with the "--denoise-noise-level" with a value greater than "0"... Which I still think it shouldn't happen. The user should always be able to control the amount of noise in the video.
Anyway, I'm doing a test to see if I can control the noise value in aomenc.
Hi tuqueque,
You should be able to see the same bug in aomenc
(in version 3.3.0 or later) if you replace the --good
option with --allintra
.
I need to discuss with the author of the libaom changelist to see how to resolve this issue. That changelist essentially turns the user-specified denoise-noise-level
value in all intra mode into a boolean that controls this new feature. This has the unintended side effect of hiding the original denoise-noise-level
feature in all intra mode.
Is there any update on this, i.e. is the issue resoloved in newer libaom versions?
I am very sorry this fell through the cracks. I believe this issue in libaom hasn't been resolved. In the latest version of libaom, the code in av1/encoder/encoder.c that I referred to in https://github.com/AOMediaCodec/libavif/issues/1137#issuecomment-1258871110 still has the same problem:
#if CONFIG_DENOISE
// even if denoise_noise_level is > 0, we don't need need to denoise on pass
// 1 of 2 if enable_dnl_denoising is disabled since the 2nd pass will be
// encoding the original (non-denoised) frame
if (cpi->oxcf.noise_level > 0 && !(cpi->oxcf.pass == AOM_RC_FIRST_PASS &&
!cpi->oxcf.enable_dnl_denoising)) {
#if !CONFIG_REALTIME_ONLY
// Choose a synthetic noise level for still images for enhanced perceptual
// quality based on an estimated noise level in the source, but only if
// the noise level is set on the command line to > 0.
if (cpi->oxcf.mode == ALLINTRA) {
// No noise synthesis if source is very clean.
// Uses a low edge threshold to focus on smooth areas.
// Increase output noise setting a little compared to measured value.
double y_noise_level = 0.0;
av1_estimate_noise_level(sd, &y_noise_level, AOM_PLANE_Y, AOM_PLANE_Y,
cm->seq_params->bit_depth, 16);
cpi->oxcf.noise_level = (float)(y_noise_level - 0.1);
cpi->oxcf.noise_level = (float)AOMMAX(0.0, cpi->oxcf.noise_level);
if (cpi->oxcf.noise_level > 0.0) {
cpi->oxcf.noise_level += (float)0.5;
}
cpi->oxcf.noise_level = (float)AOMMIN(5.0, cpi->oxcf.noise_level);
}
#endif
if (apply_denoise_2d(cpi, sd, cpi->oxcf.noise_block_size,
cpi->oxcf.noise_level, time_stamp, end_time) < 0)
res = -1;
}
#endif // CONFIG_DENOISE
I am very sorry this fell through the cracks. I believe this issue in libaom hasn't been resolved. In the latest version of libaom, the code in av1/encoder/encoder.c that I referred to in #1137 (comment) still has the same problem
Thanks - I understand that this problem would be solved for libavif if the respective commit in libaom would be reverted? https://aomedia-review.googlesource.com/c/aom/+/147641
Hello... In past versions of avifenc (6 months ago or so) I was able to use the "-a denoise-noise-level=16" command and I got a nice, subtle film grain-like noise in my avif images that greatly helped cover some minor compression artifacts when using relatively low image quality settings. I could lower the image quality further using this setting and still get fantastic looking images!
Recently, this feature is not working anymore in avifenc. I even bumped the "denoise-noise-level" value to something crazy like 100 and still got no film grain noise. I know this feature is sort of borrowed from aomenc, but this still works in aomenc perfectly, so I don't know what's going on recently in avifenc.
I hope this is sort of a bug and this fantastic feature can be brought back into avifenc. It's one of my favorite features in aomenc and avifenc!
My system: Manjaro Linux, 5.19.7-1 kernel.