6#include <QtMultimedia/private/qvideoframetexturefromsource_p.h>
7#include <QtMultimedia/private/qvideoframe_p.h>
8#include <QtMultimedia/private/qvideoframeconverter_p.h>
9#include <QtMultimedia/private/qmultimediautils_p.h>
10#include <QtMultimedia/private/qtmm_alignment_support_p.h>
12#include <QtGui/qpainter.h>
14#include <QtCore/qfile.h>
15#include <QtCore/qloggingcategory.h>
16#include <QtCore/qoperatingsystemversion.h>
31bool &glTextureExternalOesSetting()
34 qEnvironmentVariableIntValue(
"QT_MULTIMEDIA_FORCE_GL_TEXTURE_EXTERNAL_OES") != 0;
42 return glTextureExternalOesSetting();
47 glTextureExternalOesSetting() = isSet;
53 [](
int,
int) {
return 0; },
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 }, { 1, 1 }, { 1, 1 } }
121 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
127 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
133 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
139 { { 1, 1 }, { 2, 1 }, { 2, 1 } }
145 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
151 { { 2, 1 }, { 1, 1 }, { 1, 1 } }
157 { { 2, 1 }, { 1, 1 }, { 1, 1 } }
163 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
169 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
176 h += 2*(((
h/2) + 15) & ~15);
180 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
186 { { 1, 1 }, { 1, 2 }, { 1, 1 } }
193 h += 2*(((
h/2) + 15) & ~15);
197 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
203 { { 1, 1 }, { 1, 2 }, { 1, 1 } }
209 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
215 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
221 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
227 { { 1, 1 }, { 2, 2 }, { 1, 1 } }
232 [](
int,
int) {
return 0; },
234 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
240 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
245 [](
int,
int) {
return 0; },
247 { { 1, 1 }, { 1, 1 }, { 1, 1 } }
253 { { 1, 1 }, { 2, 2 }, { 2, 2 } }
257Q_GLOBAL_STATIC(QList<QRhiTexture::Format>, g_excludedRhiTextureFormats)
261 if (g_excludedRhiTextureFormats->contains(format))
265 return rhi->isTextureFormatSupported(format);
304 if (isRhiTextureFormatSupported(rhi, format))
307 QRhiTexture::Format fallbackFormat;
309 case QRhiTexture::R8:
310 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RED_OR_ALPHA8, rhi);
312 case QRhiTexture::RG8:
313 case QRhiTexture::RG16:
314 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RGBA8, rhi);
316 case QRhiTexture::R16:
317 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RG8, rhi);
319 case QRhiTexture::BGRA8:
322 fallbackFormat = resolvedRhiTextureFormat(QRhiTexture::RGBA8, rhi);
326 return QRhiTexture::UnknownFormat;
329 if (fallbackFormat == QRhiTexture::UnknownFormat) {
332 qCDebug(qLcVideoTextureHelper) <<
"Cannot determine any usable texture format, using preferred format" << format;
336 qCDebug(qLcVideoTextureHelper) <<
"Using fallback texture format" << fallbackFormat;
337 return fallbackFormat;
342 g_excludedRhiTextureFormats->swap(formats);
347 return descriptions + format;
352 switch (format.pixelFormat()) {
353 case QVideoFrameFormat::Format_SamplerExternalOES:
354 return u":/qt-project.org/multimedia/shaders/externalsampler.vert.qsb"_s;
355 case QVideoFrameFormat::Format_SamplerRect:
356 return u":/qt-project.org/multimedia/shaders/rectsampler.vert.qsb"_s;
358 return u":/qt-project.org/multimedia/shaders/vertex.vert.qsb"_s;
363 QRhiSwapChain::Format surfaceFormat)
366 switch (format.pixelFormat()) {
367 case QVideoFrameFormat::Format_Y8:
368 shaderFile = QStringLiteral(
"y");
370 case QVideoFrameFormat::Format_Y16:
371 shaderFile = QStringLiteral(
"y16");
373 case QVideoFrameFormat::Format_AYUV:
374 case QVideoFrameFormat::Format_AYUV_Premultiplied:
375 shaderFile = QStringLiteral(
"ayuv");
377 case QVideoFrameFormat::Format_ARGB8888:
378 case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
379 case QVideoFrameFormat::Format_XRGB8888:
380 shaderFile = QStringLiteral(
"argb");
382 case QVideoFrameFormat::Format_ABGR8888:
383 case QVideoFrameFormat::Format_XBGR8888:
384 shaderFile = QStringLiteral(
"abgr");
386 case QVideoFrameFormat::Format_Jpeg:
387 shaderFile = QStringLiteral(
"bgra");
389 case QVideoFrameFormat::Format_RGBA8888:
390 case QVideoFrameFormat::Format_RGBX8888:
391 shaderFile = QStringLiteral(
"rgba");
393 case QVideoFrameFormat::Format_BGRA8888:
394 case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
395 case QVideoFrameFormat::Format_BGRX8888:
399 shaderFile = !isRhiTextureFormatSupported(rhi, QRhiTexture::BGRA8)
400 ? QStringLiteral(
"bgra")
401 : QStringLiteral(
"rgba");
403 case QVideoFrameFormat::Format_YUV420P:
404 case QVideoFrameFormat::Format_YUV422P:
405 case QVideoFrameFormat::Format_IMC3:
406 shaderFile = QStringLiteral(
"yuv_triplanar");
408 case QVideoFrameFormat::Format_YUV420P10:
409 shaderFile = QStringLiteral(
"yuv_triplanar_p10");
411 case QVideoFrameFormat::Format_YV12:
412 case QVideoFrameFormat::Format_IMC1:
413 shaderFile = QStringLiteral(
"yvu_triplanar");
415 case QVideoFrameFormat::Format_IMC2:
416 shaderFile = QStringLiteral(
"imc2");
418 case QVideoFrameFormat::Format_IMC4:
419 shaderFile = QStringLiteral(
"imc4");
421 case QVideoFrameFormat::Format_UYVY:
422 shaderFile = QStringLiteral(
"uyvy");
424 case QVideoFrameFormat::Format_YUYV:
425 shaderFile = QStringLiteral(
"yuyv");
427 case QVideoFrameFormat::Format_P010:
428 case QVideoFrameFormat::Format_P016:
430 switch (format.colorTransfer()) {
431 case QVideoFrameFormat::ColorTransfer_ST2084:
432 shaderFile = QStringLiteral(
"nv12_bt2020_pq");
434 case QVideoFrameFormat::ColorTransfer_STD_B67:
435 shaderFile = QStringLiteral(
"nv12_bt2020_hlg");
438 shaderFile = QStringLiteral(
"p016");
442 case QVideoFrameFormat::Format_NV12:
443 shaderFile = QStringLiteral(
"nv12");
445 case QVideoFrameFormat::Format_NV21:
446 shaderFile = QStringLiteral(
"nv21");
448 case QVideoFrameFormat::Format_SamplerExternalOES:
449 shaderFile = QStringLiteral(
"externalsampler");
451 case QVideoFrameFormat::Format_SamplerRect:
452 shaderFile = QStringLiteral(
"rectsampler_bgra");
454 case QVideoFrameFormat::Format_Invalid:
459 if (shaderFile.isEmpty())
462 shaderFile.prepend(u":/qt-project.org/multimedia/shaders/");
464 if (surfaceFormat == QRhiSwapChain::HDRExtendedSrgbLinear)
465 shaderFile.append(u"_linear");
467 shaderFile.append(u".frag.qsb");
470 QFile::exists(shaderFile), Q_FUNC_INFO,
471 QStringLiteral(
"Shader file %1 does not exist").arg(shaderFile).toLatin1().constData());
472 qCDebug(qLcVideoTextureHelper) <<
"fragmentShaderFileName returns" << shaderFile;
510 auto colorSpace = format.colorSpace();
511 if (colorSpace == QVideoFrameFormat::ColorSpace_Undefined) {
512 if (format.frameHeight() > 576)
514 colorSpace = QVideoFrameFormat::ColorSpace_BT709;
517 colorSpace = QVideoFrameFormat::ColorSpace_BT601;
519 switch (colorSpace) {
520 case QVideoFrameFormat::ColorSpace_AdobeRgb:
522 1.0f, 0.000f, 1.402f, -0.701f,
523 1.0f, -0.344f, -0.714f, 0.529f,
524 1.0f, 1.772f, 0.000f, -0.886f,
525 0.0f, 0.000f, 0.000f, 1.000f
528 case QVideoFrameFormat::ColorSpace_BT709:
529 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
531 1.0f, 0.0f, 1.5748f, -0.790488f,
532 1.0f, -0.187324f, -0.468124f, 0.329010f,
533 1.0f, 1.855600f, 0.0f, -0.931439f,
534 0.0f, 0.0f, 0.0f, 1.0f
537 1.1644f, 0.0000f, 1.7927f, -0.9729f,
538 1.1644f, -0.2132f, -0.5329f, 0.3015f,
539 1.1644f, 2.1124f, 0.0000f, -1.1334f,
540 0.0000f, 0.0000f, 0.0000f, 1.0000f
542 case QVideoFrameFormat::ColorSpace_BT2020:
543 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
545 1.f, 0.0000f, 1.4746f, -0.7402f,
546 1.f, -0.1646f, -0.5714f, 0.3694f,
547 1.f, 1.8814f, 0.000f, -0.9445f,
548 0.0f, 0.0000f, 0.000f, 1.0000f
551 1.1644f, 0.000f, 1.6787f, -0.9157f,
552 1.1644f, -0.1874f, -0.6504f, 0.3475f,
553 1.1644f, 2.1418f, 0.0000f, -1.1483f,
554 0.0000f, 0.0000f, 0.0000f, 1.0000f
556 case QVideoFrameFormat::ColorSpace_BT601:
559 if (format.colorRange() == QVideoFrameFormat::ColorRange_Full)
561 1.f, 0.000f, 1.772f, -0.886f,
562 1.f, -0.1646f, -0.57135f, 0.36795f,
563 1.f, 1.42f, 0.000f, -0.71f,
564 0.0f, 0.000f, 0.000f, 1.0000f
567 1.164f, 0.000f, 1.596f, -0.8708f,
568 1.164f, -0.392f, -0.813f, 0.5296f,
569 1.164f, 2.017f, 0.000f, -1.0810f,
570 0.000f, 0.000f, 0.000f, 1.0000f
580 const float m1 = 1305.f/8192.f;
581 const float m2 = 2523.f/32.f;
582 const float c1 = 107.f/128.f;
583 const float c2 = 2413.f/128.f;
584 const float c3 = 2392.f/128.f;
586 const float SDR_LEVEL = 100.f;
587 sig *= SDR_LEVEL/10000.f;
588 float psig = powf(sig, m1);
589 float num = c1 + c2*psig;
590 float den = 1 + c3*psig;
591 return powf(num/den, m2);
596 const float a = 0.17883277f;
597 const float b = 0.28466892f;
598 const float c = 0.55991073f;
601 return sqrtf(3.f*sig);
602 return a*logf(12.f*sig - b) + c;
611 const QVideoFrame &frame,
const QMatrix4x4 &transform,
float opacity,
615 switch (format.pixelFormat()) {
616 case QVideoFrameFormat::Format_Invalid:
619 case QVideoFrameFormat::Format_ARGB8888:
620 case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
621 case QVideoFrameFormat::Format_XRGB8888:
622 case QVideoFrameFormat::Format_BGRA8888:
623 case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
624 case QVideoFrameFormat::Format_BGRX8888:
625 case QVideoFrameFormat::Format_ABGR8888:
626 case QVideoFrameFormat::Format_XBGR8888:
627 case QVideoFrameFormat::Format_RGBA8888:
628 case QVideoFrameFormat::Format_RGBX8888: {
629 if (format.colorRange() == QVideoFrameFormat::ColorRange_Video) {
630 constexpr float scale = 255.0f / 219.0f;
631 constexpr float offset = -16.0f / 219.0f;
634 scale, 0.f, 0.f, offset,
635 0.f, scale, 0.f, offset,
636 0.f, 0.f, scale, offset,
645 case QVideoFrameFormat::Format_Jpeg:
646 case QVideoFrameFormat::Format_Y8:
647 case QVideoFrameFormat::Format_Y16:
649 case QVideoFrameFormat::Format_IMC1:
650 case QVideoFrameFormat::Format_IMC2:
651 case QVideoFrameFormat::Format_IMC3:
652 case QVideoFrameFormat::Format_IMC4:
653 case QVideoFrameFormat::Format_AYUV:
654 case QVideoFrameFormat::Format_AYUV_Premultiplied:
655 case QVideoFrameFormat::Format_YUV420P:
656 case QVideoFrameFormat::Format_YUV420P10:
657 case QVideoFrameFormat::Format_YUV422P:
658 case QVideoFrameFormat::Format_YV12:
659 case QVideoFrameFormat::Format_UYVY:
660 case QVideoFrameFormat::Format_YUYV:
661 case QVideoFrameFormat::Format_NV12:
662 case QVideoFrameFormat::Format_NV21:
663 case QVideoFrameFormat::Format_P010:
664 case QVideoFrameFormat::Format_P016:
665 cmat = colorConversionMatrix(format);
667 case QVideoFrameFormat::Format_SamplerExternalOES:
669 if (
auto hwBuffer = QVideoFramePrivate::hwBuffer(frame))
670 cmat = hwBuffer->externalTextureMatrix();
672 case QVideoFrameFormat::Format_SamplerRect:
678 const QSize videoSize = frame.size();
679 cmat.scale(videoSize.width(), videoSize.height());
688 switch (format.colorTransfer()) {
689 case QVideoFrameFormat::ColorTransfer_ST2084:
692 case QVideoFrameFormat::ColorTransfer_STD_B67:
702 auto ud =
reinterpret_cast<
UniformData*>(dst->data());
703 memcpy(ud->transformMatrix, transform.constData(),
sizeof(ud->transformMatrix));
704 memcpy(ud->colorMatrix, cmat.constData(),
sizeof(ud->transformMatrix));
705 ud->opacity = opacity;
706 ud->width =
float(format.frameWidth());
707 ud->masteringWhite = fromLinear(
float(format.maxLuminance())/100.f);
708 ud->maxLum = fromLinear(
float(maxNits)/100.f);
709 const TextureDescription* desc = textureDescription(format.pixelFormat());
711 const bool isDmaBuf = QVideoFramePrivate::hasDmaBuf(frame);
712 using FallbackPolicy = QVideoTextureHelper::TextureDescription::FallbackPolicy;
713 auto fallbackPolicy = isDmaBuf
714 ? FallbackPolicy::Disable
715 : FallbackPolicy::Enable;
720 const bool useRedComponent =
721 !desc->hasTextureFormat(TextureDescription::Red_8)
722 || isRhiTextureFormatSupported(rhi, QRhiTexture::R8)
723 || rhi->isFeatureSupported(QRhi::RedOrAlpha8IsRed)
725 ud->redOrAlphaIndex = useRedComponent ? 0 : 3;
727 for (
int plane = 0; plane < desc->nplanes; ++plane)
728 ud->planeFormats[plane] = desc->rhiTextureFormat(plane, rhi, fallbackPolicy);
733QRhiTexture::Flags textureFlagsFor(QVideoFrameFormat::PixelFormat pixelFormat, QRhi &rhi)
735 switch (pixelFormat) {
736 case QVideoFrameFormat::Format_SamplerExternalOES:
737 if (rhi.backend() == QRhi::OpenGLES2)
738 return QRhiTexture::ExternalOES;
740 case QVideoFrameFormat::Format_SamplerRect:
741 if constexpr (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS) {
742 if (rhi.backend() == QRhi::OpenGLES2)
743 return QRhiTexture::TextureRectangleGL;
752std::unique_ptr<QRhiTexture> enqueuePlaneTextureUpload(std::unique_ptr<QRhiTexture> tex,
753 const QVideoFrame &frame, QRhi &rhi,
754 QRhiResourceUpdateBatch &rub,
int plane)
756 Q_ASSERT(frame.isMapped());
758 QVideoFrameFormat fmt = frame.surfaceFormat();
759 QVideoFrameFormat::PixelFormat pixelFormat = fmt.pixelFormat();
760 QSize size = fmt.frameSize();
762 const TextureDescription &texDesc = descriptions[pixelFormat];
763 QSize planeSize = texDesc.rhiPlaneSize(size, plane, &rhi);
764 QRhiTexture::Format format = texDesc.rhiTextureFormat(plane, &rhi);
766 bool needsRebuild = !tex || tex->pixelSize() != planeSize || tex->format() != format;
768 tex.reset(rhi.newTexture(format, planeSize, 1, {}));
770 qWarning(
"Failed to create new texture (size %dx%d)", planeSize.width(), planeSize.height());
776 tex->setFormat(format);
777 tex->setPixelSize(planeSize);
778 if (!tex->create()) {
779 qWarning(
"Failed to create texture (size %dx%d)", planeSize.width(), planeSize.height());
784 QRhiTextureSubresourceUploadDescription subresDesc;
786 if (pixelFormat == QVideoFrameFormat::Format_Jpeg) {
787 Q_ASSERT(plane == 0);
793 const QVideoFrameFormat surfaceFormat = frame.surfaceFormat();
795 const bool hasSurfaceTransform = surfaceFormat.isMirrored()
796 || surfaceFormat.scanLineDirection() == QVideoFrameFormat::BottomToTop
797 || surfaceFormat.rotation() != QtVideo::Rotation::None;
799 if (hasSurfaceTransform)
800 image = qImageFromVideoFrame(frame, VideoTransformation{});
802 image = frame.toImage();
804 image.convertTo(QImage::Format_ARGB32);
805 subresDesc.setImage(image);
809 subresDesc.setData(QByteArray::fromRawData(
810 reinterpret_cast<
const char *>(frame.bits(plane)), frame.mappedBytes(plane)));
811 subresDesc.setDataStride(frame.bytesPerLine(plane));
814 QRhiTextureUploadDescription desc({
815 QRhiTextureUploadEntry(0, 0, subresDesc),
817 rub.uploadTexture(tex.get(), desc);
822std::unique_ptr<QRhiTexture> createTextureFromHandle(QVideoFrameTexturesHandles &texturesSet,
824 QVideoFrameFormat::PixelFormat pixelFormat,
825 QSize size,
int plane)
827 const TextureDescription &texDesc = descriptions[pixelFormat];
828 QSize planeSize = texDesc.rhiPlaneSize(size, plane, &rhi);
830 if (quint64 handle = texturesSet.textureHandle(rhi, plane); handle) {
831 std::unique_ptr<QRhiTexture> tex(rhi.newTexture(texDesc.rhiTextureFormat(plane, &rhi),
833 textureFlagsFor(pixelFormat, rhi)));
834 if (tex->createFrom({ handle, 0 }))
837 qWarning(
"Failed to initialize QRhiTexture wrapper for native texture object %llu", handle);
842std::optional<RhiTextureArray> createTextureWrappers(QVideoFrameTexturesHandles &texturesSet,
844 QVideoFrameFormat::PixelFormat pixelFormat,
847 const QVideoFrameFormat::PixelFormat texturesFormat =
848 texturesSet.texturePixelFormat().value_or(pixelFormat);
849 const TextureDescription &texDesc = descriptions[texturesFormat];
850 RhiTextureArray textures;
851 for (
int plane = 0; plane < texDesc.nplanes; ++plane) {
852 textures[plane] = QVideoTextureHelper::createTextureFromHandle(texturesSet, rhi,
853 texturesFormat, size, plane);
854 if (!textures[plane])
857 return std::optional<RhiTextureArray>(std::move(textures));
860QVideoFrameTexturesUPtr makeBorrowedTextures(QRhi &rhi, QVideoFrameTexturesHandles &texturesSet,
861 QVideoFrameFormat::PixelFormat pixelFormat, QSize size,
862 QVideoFrame sourceFrame)
864 auto wrappers = createTextureWrappers(texturesSet, rhi, pixelFormat, size);
867 return std::make_unique<QVideoFrameTexturesFromRhiTextureArray>(std::move(*wrappers),
868 std::move(sourceFrame));
871QVideoFrameTexturesUPtr makeOwnedTextures(QRhi &rhi, QVideoFrameTexturesHandlesUPtr handles,
872 QVideoFrameFormat::PixelFormat pixelFormat, QSize size,
873 QVideoFrame sourceFrame)
875 auto wrappers = createTextureWrappers(*handles, rhi, pixelFormat, size);
878 return std::make_unique<QVideoFrameTexturesFromHandlesSet>(
879 std::move(*wrappers), std::move(handles), std::move(sourceFrame));
886 QVideoFrameFormat::PixelFormat pixelFormat,
887 QSize size, QVideoFrame sourceFrame)
892 if (pixelFormat == QVideoFrameFormat::Format_Invalid)
898 return makeOwnedTextures(rhi, std::move(texturesSet), pixelFormat, size,
899 std::move(sourceFrame));
905 auto *raw = oldTextures.release();
906 auto *rawFromMemory =
dynamic_cast<QVideoFrameTexturesFromMemory *>(raw);
907 if (!rawFromMemory) {
911 return std::unique_ptr<QVideoFrameTexturesFromMemory>(rawFromMemory);
915 QRhiResourceUpdateBatch &rub,
916 QVideoFrameTexturesUPtr oldTextures)
918 qCDebug(qLcVideoTextureHelper) <<
"createTexturesFromMemory, pixelFormat:" << frame.pixelFormat();
919 if (!frame.map(QVideoFrame::ReadOnly)) {
920 qWarning() <<
"Cannot map a video frame in ReadOnly mode!";
924 auto unmapFrameGuard = qScopeGuard([&] {
928 const TextureDescription &texDesc = descriptions[frame.surfaceFormat().pixelFormat()];
930 std::optional<RhiTextureArray> recycledArray;
931 if (
auto recycled = tryRecycleMemory(std::move(oldTextures)))
932 recycledArray =
std::move(*recycled).takeTextureArray();
934 RhiTextureArray textureArray;
935 for (quint8 plane = 0; plane < texDesc.nplanes; ++plane) {
936 std::unique_ptr<QRhiTexture> slot =
937 recycledArray ? std::move((*recycledArray)[plane]) :
nullptr;
939 auto planeTexture = enqueuePlaneTextureUpload(
std::move(slot), frame, rhi, rub, plane);
942 textureArray[plane] =
std::move(planeTexture);
945 unmapFrameGuard.dismiss();
946 return std::make_unique<QVideoFrameTexturesFromMemory>(std::move(textureArray),
951 QRhiResourceUpdateBatch &rub,
952 QVideoFrameTexturesUPtr &oldTextures)
954 if (!frame.isValid())
957 if (QHwVideoBuffer *hwBuffer = QVideoFramePrivate::hwBuffer(frame)) {
958 if (
auto textures = hwBuffer->mapTextures(rhi, oldTextures))
961 QVideoFrameFormat format = frame.surfaceFormat();
962 if (
auto textures = makeBorrowedTextures(rhi, *hwBuffer, format.pixelFormat(),
963 format.frameSize(), frame))
967 return createTexturesFromMemory(frame, rhi, rub, std::move(oldTextures));
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 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)
static QMatrix4x4 colorConversionMatrix(const QVideoFrameFormat &format)
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...
void setForceGlTextureExternalOesIsSet(bool isSet)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)