10#include "private/qmultimediautils_p.h"
11#include "private/qtmm_alignment_support_p.h"
13#include <QtCore/qfile.h>
15#include <qloggingcategory.h>
27 static const bool isSet =
28 qEnvironmentVariableIntValue(
"QT_MULTIMEDIA_FORCE_GL_TEXTURE_EXTERNAL_OES") != 0;
35 [](
int,
int) {
return 0; },
37 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
43 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
49 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
55 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
61 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
67 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
73 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
79 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
85 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
91 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
97 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
103 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
109 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
115 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
121 { { 1, 1 }, { 2, 1 }, { 2, 1 } }
127 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
133 { { 2, 1 }, { 1, 1 }, { 1, 1 } }
139 { { 2, 1 }, { 1, 1 }, { 1, 1 } }
145 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
151 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
158 h += 2*(((
h/2) + 15) & ~15);
162 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
168 { { 1, 1 }, { 1, 2 }, { 1, 1 } }
175 h += 2*(((
h/2) + 15) & ~15);
179 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
185 { { 1, 1 }, { 1, 2 }, { 1, 1 } }
191 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
197 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
203 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
209 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
214 [](
int,
int) {
return 0; },
216 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
222 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
227 [](
int,
int) {
return 0; },
229 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
235 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
239Q_GLOBAL_STATIC(QList<QRhiTexture::Format>, g_excludedRhiTextureFormats)
243 if (g_excludedRhiTextureFormats->contains(format))
247 return rhi->isTextureFormatSupported(format);
286 if (isRhiTextureFormatSupported(rhi, format))
289 QRhiTexture::Format fallbackFormat;
291 case QRhiTexture::R8:
292 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RED_OR_ALPHA8, rhi);
294 case QRhiTexture::RG8:
295 case QRhiTexture::RG16:
296 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RGBA8, rhi);
298 case QRhiTexture::R16:
299 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RG8, rhi);
301 case QRhiTexture::BGRA8:
304 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RGBA8, rhi);
308 return QRhiTexture::UnknownFormat;
311 if (fallbackFormat == QRhiTexture::UnknownFormat) {
314 qCDebug(qLcVideoTextureHelper) <<
"Cannot determine any usable texture format, using preferred format" << format;
318 qCDebug(qLcVideoTextureHelper) <<
"Using fallback texture format" << fallbackFormat;
319 return fallbackFormat;
324 g_excludedRhiTextureFormats->swap(formats);
329 return descriptions + format;
334 auto fmt = format.pixelFormat();
338 if (fmt == QVideoFrameFormat::Format_SamplerExternalOES)
339 return QStringLiteral(
":/qt-project.org/multimedia/shaders/externalsampler.vert.qsb");
342 if (fmt == QVideoFrameFormat::Format_SamplerRect)
343 return QStringLiteral(
":/qt-project.org/multimedia/shaders/rectsampler.vert.qsb");
346 return QStringLiteral(
":/qt-project.org/multimedia/shaders/vertex.vert.qsb");
350 QRhiSwapChain::Format surfaceFormat)
353 switch (format.pixelFormat()) {
354 case QVideoFrameFormat::Format_Y8:
355 shaderFile = QStringLiteral(
"y");
357 case QVideoFrameFormat::Format_Y16:
358 shaderFile = QStringLiteral(
"y16");
360 case QVideoFrameFormat::Format_AYUV:
361 case QVideoFrameFormat::Format_AYUV_Premultiplied:
362 shaderFile = QStringLiteral(
"ayuv");
364 case QVideoFrameFormat::Format_ARGB8888:
365 case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
366 case QVideoFrameFormat::Format_XRGB8888:
367 shaderFile = QStringLiteral(
"argb");
369 case QVideoFrameFormat::Format_ABGR8888:
370 case QVideoFrameFormat::Format_XBGR8888:
371 shaderFile = QStringLiteral(
"abgr");
373 case QVideoFrameFormat::Format_Jpeg:
374 shaderFile = QStringLiteral(
"bgra");
376 case QVideoFrameFormat::Format_RGBA8888:
377 case QVideoFrameFormat::Format_RGBX8888:
378 shaderFile = QStringLiteral(
"rgba");
380 case QVideoFrameFormat::Format_BGRA8888:
381 case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
382 case QVideoFrameFormat::Format_BGRX8888:
386 shaderFile = !isRhiTextureFormatSupported(rhi, QRhiTexture::BGRA8)
387 ? QStringLiteral(
"bgra")
388 : QStringLiteral(
"rgba");
390 case QVideoFrameFormat::Format_YUV420P:
391 case QVideoFrameFormat::Format_YUV422P:
392 case QVideoFrameFormat::Format_IMC3:
393 shaderFile = QStringLiteral(
"yuv_triplanar");
395 case QVideoFrameFormat::Format_YUV420P10:
396 shaderFile = QStringLiteral(
"yuv_triplanar_p10");
398 case QVideoFrameFormat::Format_YV12:
399 case QVideoFrameFormat::Format_IMC1:
400 shaderFile = QStringLiteral(
"yvu_triplanar");
402 case QVideoFrameFormat::Format_IMC2:
403 shaderFile = QStringLiteral(
"imc2");
405 case QVideoFrameFormat::Format_IMC4:
406 shaderFile = QStringLiteral(
"imc4");
408 case QVideoFrameFormat::Format_UYVY:
409 shaderFile = QStringLiteral(
"uyvy");
411 case QVideoFrameFormat::Format_YUYV:
412 shaderFile = QStringLiteral(
"yuyv");
414 case QVideoFrameFormat::Format_P010:
415 case QVideoFrameFormat::Format_P016:
417 if (format.colorTransfer() == QVideoFrameFormat::ColorTransfer_ST2084) {
418 shaderFile = QStringLiteral(
"nv12_bt2020_pq");
421 if (format.colorTransfer() == QVideoFrameFormat::ColorTransfer_STD_B67) {
422 shaderFile = QStringLiteral(
"nv12_bt2020_hlg");
425 shaderFile = QStringLiteral(
"p016");
427 case QVideoFrameFormat::Format_NV12:
428 shaderFile = QStringLiteral(
"nv12");
430 case QVideoFrameFormat::Format_NV21:
431 shaderFile = QStringLiteral(
"nv21");
433 case QVideoFrameFormat::Format_SamplerExternalOES:
435 shaderFile = QStringLiteral(
"externalsampler");
438 case QVideoFrameFormat::Format_SamplerRect:
440 shaderFile = QStringLiteral(
"rectsampler_bgra");
444 case QVideoFrameFormat::Format_Invalid:
449 if (shaderFile.isEmpty())
452 shaderFile.prepend(u":/qt-project.org/multimedia/shaders/");
454 if (surfaceFormat == QRhiSwapChain::HDRExtendedSrgbLinear)
455 shaderFile.append(u"_linear");
457 shaderFile.append(u".frag.qsb");
460 QFile::exists(shaderFile), Q_FUNC_INFO,
461 QStringLiteral(
"Shader file %1 does not exist").arg(shaderFile).toLatin1().constData());
462 qCDebug(qLcVideoTextureHelper) <<
"fragmentShaderFileName returns" << shaderFile;
500 auto colorSpace = format.colorSpace();
501 if (colorSpace == QVideoFrameFormat::ColorSpace_Undefined) {
502 if (format.frameHeight() > 576)
504 colorSpace = QVideoFrameFormat::ColorSpace_BT709;
507 colorSpace = QVideoFrameFormat::ColorSpace_BT601;
509 switch (colorSpace) {
510 case QVideoFrameFormat::ColorSpace_AdobeRgb:
512 1.0f, 0.000f, 1.402f, -0.701f,
513 1.0f, -0.344f, -0.714f, 0.529f,
514 1.0f, 1.772f, 0.000f, -0.886f,
515 0.0f, 0.000f, 0.000f, 1.000f
518 case QVideoFrameFormat::ColorSpace_BT709:
519 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
521 1.0f, 0.0f, 1.5748f, -0.790488f,
522 1.0f, -0.187324f, -0.468124f, 0.329010f,
523 1.0f, 1.855600f, 0.0f, -0.931439f,
524 0.0f, 0.0f, 0.0f, 1.0f
527 1.1644f, 0.0000f, 1.7927f, -0.9729f,
528 1.1644f, -0.2132f, -0.5329f, 0.3015f,
529 1.1644f, 2.1124f, 0.0000f, -1.1334f,
530 0.0000f, 0.0000f, 0.0000f, 1.0000f
532 case QVideoFrameFormat::ColorSpace_BT2020:
533 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
535 1.f, 0.0000f, 1.4746f, -0.7402f,
536 1.f, -0.1646f, -0.5714f, 0.3694f,
537 1.f, 1.8814f, 0.000f, -0.9445f,
538 0.0f, 0.0000f, 0.000f, 1.0000f
541 1.1644f, 0.000f, 1.6787f, -0.9157f,
542 1.1644f, -0.1874f, -0.6504f, 0.3475f,
543 1.1644f, 2.1418f, 0.0000f, -1.1483f,
544 0.0000f, 0.0000f, 0.0000f, 1.0000f
546 case QVideoFrameFormat::ColorSpace_BT601:
549 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
551 1.f, 0.000f, 1.772f, -0.886f,
552 1.f, -0.1646f, -0.57135f, 0.36795f,
553 1.f, 1.42f, 0.000f, -0.71f,
554 0.0f, 0.000f, 0.000f, 1.0000f
557 1.164f, 0.000f, 1.596f, -0.8708f,
558 1.164f, -0.392f, -0.813f, 0.5296f,
559 1.164f, 2.017f, 0.000f, -1.0810f,
560 0.000f, 0.000f, 0.000f, 1.0000f
570 const float m1 = 1305.f/8192.f;
571 const float m2 = 2523.f/32.f;
572 const float c1 = 107.f/128.f;
573 const float c2 = 2413.f/128.f;
574 const float c3 = 2392.f/128.f;
576 const float SDR_LEVEL = 100.f;
577 sig *= SDR_LEVEL/10000.f;
578 float psig = powf(sig, m1);
579 float num = c1 + c2*psig;
580 float den = 1 + c3*psig;
581 return powf(num/den, m2);
586 const float a = 0.17883277f;
587 const float b = 0.28466892f;
588 const float c = 0.55991073f;
591 return sqrtf(3.f*sig);
592 return a*logf(12.f*sig - b) + c;
601 const QVideoFrame &frame,
const QMatrix4x4 &transform,
float opacity,
609 switch (format.pixelFormat()) {
610 case QVideoFrameFormat::Format_Invalid:
613 case QVideoFrameFormat::Format_ARGB8888:
614 case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
615 case QVideoFrameFormat::Format_XRGB8888:
616 case QVideoFrameFormat::Format_BGRA8888:
617 case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
618 case QVideoFrameFormat::Format_BGRX8888:
619 case QVideoFrameFormat::Format_ABGR8888:
620 case QVideoFrameFormat::Format_XBGR8888:
621 case QVideoFrameFormat::Format_RGBA8888:
622 case QVideoFrameFormat::Format_RGBX8888: {
623 if (format.colorRange() == QVideoFrameFormat::ColorRange_Video) {
624 constexpr float scale = 255.0f / 219.0f;
625 constexpr float offset = -16.0f / 219.0f;
628 scale, 0.f, 0.f, offset,
629 0.f, scale, 0.f, offset,
630 0.f, 0.f, scale, offset,
639 case QVideoFrameFormat::Format_Jpeg:
640 case QVideoFrameFormat::Format_Y8:
641 case QVideoFrameFormat::Format_Y16:
643 case QVideoFrameFormat::Format_IMC1:
644 case QVideoFrameFormat::Format_IMC2:
645 case QVideoFrameFormat::Format_IMC3:
646 case QVideoFrameFormat::Format_IMC4:
647 case QVideoFrameFormat::Format_AYUV:
648 case QVideoFrameFormat::Format_AYUV_Premultiplied:
649 case QVideoFrameFormat::Format_YUV420P:
650 case QVideoFrameFormat::Format_YUV420P10:
651 case QVideoFrameFormat::Format_YUV422P:
652 case QVideoFrameFormat::Format_YV12:
653 case QVideoFrameFormat::Format_UYVY:
654 case QVideoFrameFormat::Format_YUYV:
655 case QVideoFrameFormat::Format_NV12:
656 case QVideoFrameFormat::Format_NV21:
657 case QVideoFrameFormat::Format_P010:
658 case QVideoFrameFormat::Format_P016:
659 cmat = colorMatrix(format);
661 case QVideoFrameFormat::Format_SamplerExternalOES:
663 if (
auto hwBuffer = QVideoFramePrivate::hwBuffer(frame))
664 cmat = hwBuffer->externalTextureMatrix();
666 case QVideoFrameFormat::Format_SamplerRect:
672 const QSize videoSize = frame.size();
673 cmat.scale(videoSize.width(), videoSize.height());
682 switch (format.colorTransfer()) {
683 case QVideoFrameFormat::ColorTransfer_ST2084:
686 case QVideoFrameFormat::ColorTransfer_STD_B67:
696 auto ud =
reinterpret_cast<
UniformData*>(dst->data());
697 memcpy(ud->transformMatrix, transform.constData(),
sizeof(ud->transformMatrix));
698 memcpy(ud->colorMatrix, cmat.constData(),
sizeof(ud->transformMatrix));
699 ud->opacity = opacity;
700 ud->width =
float(format.frameWidth());
701 ud->masteringWhite = fromLinear(
float(format.maxLuminance())/100.f);
702 ud->maxLum = fromLinear(
float(maxNits)/100.f);
703 const TextureDescription* desc = textureDescription(format.pixelFormat());
706 using FallbackPolicy = QVideoTextureHelper::TextureDescription::FallbackPolicy;
707 auto fallbackPolicy = isDmaBuf
708 ? FallbackPolicy::Disable
709 : FallbackPolicy::Enable;
714 const bool useRedComponent =
715 !desc->hasTextureFormat(TextureDescription::Red_8)
716 || isRhiTextureFormatSupported(rhi, QRhiTexture::R8)
717 || rhi->isFeatureSupported(QRhi::RedOrAlpha8IsRed)
719 ud->redOrAlphaIndex = useRedComponent ? 0 : 3;
721 for (
int plane = 0; plane < desc->nplanes; ++plane)
722 ud->planeFormats[plane] = desc->rhiTextureFormat(plane, rhi, fallbackPolicy);
727QRhiTexture::Flags textureFlagsFor(QVideoFrameFormat::PixelFormat pixelFormat,
728 [[maybe_unused]] QRhi &rhi)
730 switch (pixelFormat) {
731 case QVideoFrameFormat::Format_SamplerExternalOES:
733 if (rhi.backend() == QRhi::OpenGLES2)
734 return QRhiTexture::ExternalOES;
737 case QVideoFrameFormat::Format_SamplerRect:
739 if (rhi.backend() == QRhi::OpenGLES2)
740 return QRhiTexture::TextureRectangleGL;
749std::unique_ptr<QRhiTexture> ensurePlaneTexture(std::unique_ptr<QRhiTexture> tex,
750 const QVideoFrame &frame, QRhi &rhi,
751 QRhiResourceUpdateBatch &rub,
int plane)
753 Q_ASSERT(frame.isMapped());
755 QVideoFrameFormat fmt = frame.surfaceFormat();
756 QVideoFrameFormat::PixelFormat pixelFormat = fmt.pixelFormat();
757 QSize size = fmt.frameSize();
759 const TextureDescription &texDesc = descriptions[pixelFormat];
760 QSize planeSize = texDesc.rhiPlaneSize(size, plane, &rhi);
761 QRhiTexture::Format format = texDesc.rhiTextureFormat(plane, &rhi);
763 bool needsRebuild = !tex || tex->pixelSize() != planeSize || tex->format() != format;
765 tex.reset(rhi.newTexture(format, planeSize, 1, {}));
767 qWarning(
"Failed to create new texture (size %dx%d)", planeSize.width(), planeSize.height());
773 tex->setFormat(format);
774 tex->setPixelSize(planeSize);
775 if (!tex->create()) {
776 qWarning(
"Failed to create texture (size %dx%d)", planeSize.width(), planeSize.height());
783 if (pixelFormat == QVideoFrameFormat::Format_Jpeg) {
784 Q_ASSERT(plane == 0);
790 const QVideoFrameFormat surfaceFormat = frame.surfaceFormat();
792 const bool hasSurfaceTransform = surfaceFormat.isMirrored()
793 || surfaceFormat.scanLineDirection() == QVideoFrameFormat::BottomToTop
794 || surfaceFormat.rotation() != QtVideo::Rotation::None;
796 if (hasSurfaceTransform)
797 image = qImageFromVideoFrame(frame, VideoTransformation{});
799 image = frame.toImage();
801 image.convertTo(QImage::Format_ARGB32);
802 subresDesc.setImage(image);
806 subresDesc.setData(QByteArray::fromRawData(
807 reinterpret_cast<
const char *>(frame.bits(plane)), frame.mappedBytes(plane)));
808 subresDesc.setDataStride(frame.bytesPerLine(plane));
813 rub.uploadTexture(tex.get(), desc);
818std::unique_ptr<QRhiTexture> createTextureFromHandle(QVideoFrameTexturesHandles &texturesSet,
820 QVideoFrameFormat::PixelFormat pixelFormat,
821 QSize size,
int plane)
823 const TextureDescription &texDesc = descriptions[pixelFormat];
824 QSize planeSize = texDesc.rhiPlaneSize(size, plane, &rhi);
826 if (quint64 handle = texturesSet.textureHandle(rhi, plane); handle) {
827 std::unique_ptr<QRhiTexture> tex(rhi.newTexture(texDesc.rhiTextureFormat(plane, &rhi),
829 textureFlagsFor(pixelFormat, rhi)));
830 if (tex->createFrom({ handle, 0 }))
833 qWarning(
"Failed to initialize QRhiTexture wrapper for native texture object %llu", handle);
838std::optional<RhiTextureArray> buildWrappers(QVideoFrameTexturesHandles &texturesSet, QRhi &rhi,
839 QVideoFrameFormat::PixelFormat pixelFormat, QSize size)
841 const TextureDescription &texDesc = descriptions[pixelFormat];
842 RhiTextureArray textures;
843 for (quint8 plane = 0; plane < texDesc.nplanes; ++plane) {
844 textures[plane] = QVideoTextureHelper::createTextureFromHandle(texturesSet, rhi,
845 pixelFormat, size, plane);
846 if (!textures[plane])
849 return std::optional<RhiTextureArray>(std::move(textures));
852QVideoFrameTexturesUPtr makeBorrowed(QRhi &rhi, QVideoFrameTexturesHandles &texturesSet,
853 QVideoFrameFormat::PixelFormat pixelFormat, QSize size,
854 QVideoFrame sourceFrame)
856 auto wrappers = buildWrappers(texturesSet, rhi, pixelFormat, size);
860 std::move(sourceFrame));
863QVideoFrameTexturesUPtr makeOwned(QRhi &rhi, QVideoFrameTexturesHandles &texturesSet,
864 QVideoFrameTexturesHandlesUPtr handles,
865 QVideoFrameFormat::PixelFormat pixelFormat, QSize size,
866 QVideoFrame sourceFrame)
868 auto wrappers = buildWrappers(texturesSet, rhi, pixelFormat, size);
872 std::move(*wrappers),
std::move(handles),
std::move(sourceFrame));
879 QVideoFrameFormat::PixelFormat pixelFormat,
880 QSize size, QVideoFrame sourceFrame)
885 if (pixelFormat == QVideoFrameFormat::Format_Invalid)
891 auto &texturesSetRef = *texturesSet;
892 return makeOwned(rhi, texturesSetRef, std::move(texturesSet), pixelFormat, size,
893 std::move(sourceFrame));
902 oldTextures.release();
903 return std::unique_ptr<QVideoFrameTexturesFromMemory>(raw);
907 QRhiResourceUpdateBatch &rub,
908 QVideoFrameTexturesUPtr oldTextures)
910 qCDebug(qLcVideoTextureHelper) <<
"createTexturesFromMemory, pixelFormat:" << frame.pixelFormat();
911 if (!frame.map(QVideoFrame::ReadOnly)) {
912 qWarning() <<
"Cannot map a video frame in ReadOnly mode!";
916 auto unmapFrameGuard = qScopeGuard([&] {
920 const TextureDescription &texDesc = descriptions[frame.surfaceFormat().pixelFormat()];
922 std::optional<RhiTextureArray> recycledArray;
923 if (
auto recycled = tryRecycleMemory(std::move(oldTextures)))
924 recycledArray =
std::move(*recycled).takeTextureArray();
926 RhiTextureArray textureArray;
927 for (quint8 plane = 0; plane < texDesc.nplanes; ++plane) {
928 std::unique_ptr<QRhiTexture> slot =
929 recycledArray ?
std::move((*recycledArray)[plane]) :
nullptr;
931 auto planeTexture = ensurePlaneTexture(std::move(slot), frame, rhi, rub, plane);
934 textureArray[plane] =
std::move(planeTexture);
937 unmapFrameGuard.dismiss();
943 QRhiResourceUpdateBatch &rub,
944 QVideoFrameTexturesUPtr &oldTextures)
946 if (!frame.isValid())
949 if (QHwVideoBuffer *hwBuffer = QVideoFramePrivate::hwBuffer(frame)) {
950 if (
auto textures = hwBuffer->mapTextures(rhi, oldTextures))
953 QVideoFrameFormat format = frame.surfaceFormat();
955 makeBorrowed(rhi, *hwBuffer, format.pixelFormat(), format.frameSize(), frame))
959 return createTexturesFromMemory(frame, rhi, rub, std::move(oldTextures));
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
static bool hasDmaBuf(const QVideoFrame &frame)
~QVideoFrameTexturesFromHandlesSet() override
~QVideoFrameTexturesFromMemory() override
QRhiTexture::Format resolvedRhiTextureFormat(QRhiTexture::Format format, QRhi *rhi)
Returns a QRhiTexture::Format taking into account rhi capabilities and explicitly excluded formats us...
float convertHLGFromLinear(float sig)
static QMatrix4x4 colorMatrix(const QVideoFrameFormat &format)
static float convertPQFromLinear(float sig)
static float convertSDRFromLinear(float sig)
void setExcludedRhiTextureFormats(QList< QRhiTexture::Format > formats)
static std::unique_ptr< QVideoFrameTexturesFromMemory > tryRecycleMemory(QVideoFrameTexturesUPtr oldTextures)
QVideoFrameTexturesUPtr createTextures(const QVideoFrame &frame, QRhi &rhi, QRhiResourceUpdateBatch &rub, QVideoFrameTexturesUPtr &oldTextures)
Creates plane textures from a video frame by the specified rhi. If possible, the function modifies 'o...
QString fragmentShaderFileName(const QVideoFrameFormat &format, QRhi *rhi, QRhiSwapChain::Format surfaceFormat)
const TextureDescription * textureDescription(QVideoFrameFormat::PixelFormat format)
static bool isRhiTextureFormatSupported(const QRhi *rhi, QRhiTexture::Format format)
static QVideoFrameTexturesUPtr createTexturesFromMemory(QVideoFrame frame, QRhi &rhi, QRhiResourceUpdateBatch &rub, QVideoFrameTexturesUPtr oldTextures)
bool forceGlTextureExternalOesIsSet()
QString vertexShaderFileName(const QVideoFrameFormat &format)
static const TextureDescription descriptions[QVideoFrameFormat::NPixelFormats]
void updateUniformData(QByteArray *dst, QRhi *rhi, const QVideoFrameFormat &format, const QVideoFrame &frame, const QMatrix4x4 &transform, float opacity, float maxNits)
QVideoFrameTexturesUPtr createTexturesFromHandles(QVideoFrameTexturesHandlesUPtr texturesSet, QRhi &rhi, QVideoFrameFormat::PixelFormat pixelFormat, QSize size, QVideoFrame sourceFrame)
Creates plane textures from texture handles set by the specified rhi. The result owns the specified h...
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)