From 6458c9ae52f0e7b8b98cda1b0a3931430aee1145 Mon Sep 17 00:00:00 2001 From: Daniel Novomesky Date: Wed, 22 Sep 2021 11:53:46 +0200 Subject: [PATCH] avif: performance and quality improvements Enable decoder to use more threads. 8bit YUV->RGB conversion is significantly faster when AVIF_RGB_FORMAT_RGBA format is used, because libavif can use libyuv to perform conversion quickly. Prefer faster AVIF_CHROMA_UPSAMPLING_FASTEST when decoding animation. Encoder speed changed from to 8 to 7. Recent AV1 encoders got faster, so it is OK to switch to better compression quality. Remove obsolete image/avif-sequence mime-type as it was merged with image/avif. --- src/imageformats/avif.cpp | 22 +++++++++++++++------- src/imageformats/avif.json | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/imageformats/avif.cpp b/src/imageformats/avif.cpp index 99be08e..5593952 100644 --- a/src/imageformats/avif.cpp +++ b/src/imageformats/avif.cpp @@ -97,6 +97,10 @@ bool QAVIFHandler::ensureDecoder() m_decoder = avifDecoderCreate(); +#if AVIF_VERSION >= 80400 + m_decoder->maxThreads = qBound(1, QThread::idealThreadCount(), 64); +#endif + #if AVIF_VERSION >= 90100 m_decoder->strictFlags = AVIF_STRICT_DISABLED; #endif @@ -184,7 +188,7 @@ bool QAVIFHandler::decode_one_frame() if (loadalpha) { resultformat = QImage::Format_RGBA8888; } else { - resultformat = QImage::Format_RGB888; + resultformat = QImage::Format_RGBX8888; } } QImage result(m_decoder->image->width, m_decoder->image->height, resultformat); @@ -276,20 +280,24 @@ bool QAVIFHandler::decode_one_frame() rgb.format = AVIF_RGB_FORMAT_RGBA; if (!loadalpha) { - rgb.ignoreAlpha = AVIF_TRUE; - result.fill(Qt::black); if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) { resultformat = QImage::Format_Grayscale16; } } } else { rgb.depth = 8; + rgb.format = AVIF_RGB_FORMAT_RGBA; + +#if AVIF_VERSION >= 80400 + if (m_decoder->imageCount > 1) { + /* accelerate animated AVIF */ + rgb.chromaUpsampling = AVIF_CHROMA_UPSAMPLING_FASTEST; + } +#endif + if (loadalpha) { - rgb.format = AVIF_RGB_FORMAT_RGBA; resultformat = QImage::Format_ARGB32; } else { - rgb.format = AVIF_RGB_FORMAT_RGB; - if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) { resultformat = QImage::Format_Grayscale8; } else { @@ -710,7 +718,7 @@ bool QAVIFHandler::write(const QImage &image) encoder->maxQuantizerAlpha = maxQuantizerAlpha; } - encoder->speed = 8; + encoder->speed = 7; res = avifEncoderWrite(encoder, avif, &raw); avifEncoderDestroy(encoder); diff --git a/src/imageformats/avif.json b/src/imageformats/avif.json index 47d06b4..c187ca6 100644 --- a/src/imageformats/avif.json +++ b/src/imageformats/avif.json @@ -1,4 +1,4 @@ { "Keys": [ "avif", "avifs" ], - "MimeTypes": [ "image/avif", "image/avif-sequence" ] + "MimeTypes": [ "image/avif", "image/avif" ] }