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.
This commit is contained in:
Daniel Novomesky
2021-09-22 11:53:46 +02:00
parent 45cd128f73
commit 6458c9ae52
2 changed files with 16 additions and 8 deletions

View File

@ -97,6 +97,10 @@ bool QAVIFHandler::ensureDecoder()
m_decoder = avifDecoderCreate(); m_decoder = avifDecoderCreate();
#if AVIF_VERSION >= 80400
m_decoder->maxThreads = qBound(1, QThread::idealThreadCount(), 64);
#endif
#if AVIF_VERSION >= 90100 #if AVIF_VERSION >= 90100
m_decoder->strictFlags = AVIF_STRICT_DISABLED; m_decoder->strictFlags = AVIF_STRICT_DISABLED;
#endif #endif
@ -184,7 +188,7 @@ bool QAVIFHandler::decode_one_frame()
if (loadalpha) { if (loadalpha) {
resultformat = QImage::Format_RGBA8888; resultformat = QImage::Format_RGBA8888;
} else { } else {
resultformat = QImage::Format_RGB888; resultformat = QImage::Format_RGBX8888;
} }
} }
QImage result(m_decoder->image->width, m_decoder->image->height, resultformat); 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; rgb.format = AVIF_RGB_FORMAT_RGBA;
if (!loadalpha) { if (!loadalpha) {
rgb.ignoreAlpha = AVIF_TRUE;
result.fill(Qt::black);
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) { if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
resultformat = QImage::Format_Grayscale16; resultformat = QImage::Format_Grayscale16;
} }
} }
} else { } else {
rgb.depth = 8; 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) { if (loadalpha) {
rgb.format = AVIF_RGB_FORMAT_RGBA;
resultformat = QImage::Format_ARGB32; resultformat = QImage::Format_ARGB32;
} else { } else {
rgb.format = AVIF_RGB_FORMAT_RGB;
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) { if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
resultformat = QImage::Format_Grayscale8; resultformat = QImage::Format_Grayscale8;
} else { } else {
@ -710,7 +718,7 @@ bool QAVIFHandler::write(const QImage &image)
encoder->maxQuantizerAlpha = maxQuantizerAlpha; encoder->maxQuantizerAlpha = maxQuantizerAlpha;
} }
encoder->speed = 8; encoder->speed = 7;
res = avifEncoderWrite(encoder, avif, &raw); res = avifEncoderWrite(encoder, avif, &raw);
avifEncoderDestroy(encoder); avifEncoderDestroy(encoder);

View File

@ -1,4 +1,4 @@
{ {
"Keys": [ "avif", "avifs" ], "Keys": [ "avif", "avifs" ],
"MimeTypes": [ "image/avif", "image/avif-sequence" ] "MimeTypes": [ "image/avif", "image/avif" ]
} }