42 [[maybe_unused]] const GstVideoInfo &info,
43 [[maybe_unused]] QVideoFrameFormat format,
45#if defined(QGC_HAS_GST_DMABUF_GPU_PATH)
46 EGLDisplay eglDisplay,
50#if defined(QGC_HAS_GST_AHARDWAREBUFFER_GPU_PATH)
51 EGLDisplay ahbEglDisplay,
58 if (!gpuEnabled || !sample) {
62 GstBuffer *buffer = gst_sample_get_buffer(sample);
68 GstMemory *mem0 = gst_buffer_peek_memory(buffer, 0);
74 auto buildOrFallback = [&matchedPath](
auto &&buf) -> std::unique_ptr<QHwVideoBuffer> {
75 if (!buf || !buf->validatePlaneHandles()) {
76 static std::atomic<quint64> s_validateFails{0};
77 const quint64 c = s_validateFails.fetch_add(1, std::memory_order_relaxed) + 1;
78 if ((c & 0x3F) == 1) {
79 qCWarning(GstHwBufFactoryLog)
80 <<
"validatePlaneHandles failed — CPU memcpy fallback (total:" << c <<
")";
85 return std::move(buf);
88#if defined(QGC_HAS_GST_DMABUF_GPU_PATH)
89 if (eglDisplay != EGL_NO_DISPLAY && gst_is_dmabuf_memory(mem0)) {
96 static const bool isEglfsQPA =
97 QGuiApplication::platformName() == QLatin1String(
"eglfs");
99 && (format.pixelFormat() == QVideoFrameFormat::Format_UYVY
100 || format.pixelFormat() == QVideoFrameFormat::Format_YUYV)) {
101 QVideoFrameFormat spoofed(format.frameSize(), QVideoFrameFormat::Format_RGBA8888);
102 spoofed.setStreamFrameRate(format.streamFrameRate());
103 spoofed.setColorRange(format.colorRange());
104 spoofed.setColorSpace(format.colorSpace());
105 spoofed.setColorTransfer(format.colorTransfer());
106 spoofed.setViewport(format.viewport());
107 format = std::move(spoofed);
109 return buildOrFallback(std::make_unique<GstDmaBufVideoBuffer>(sample, info, format, eglDisplay));
113#if defined(QGC_HAS_GST_GLMEMORY_GPU_PATH)
114 if (gst_is_gl_memory(mem0)) {
116 return buildOrFallback(std::make_unique<GstGlVideoBuffer>(sample, info, format));
120#if defined(QGC_HAS_GST_D3D11_GPU_PATH)
121 if (gst_is_d3d11_memory(mem0)) {
123 return buildOrFallback(std::make_unique<GstD3D11VideoBuffer>(sample, info, format));
127#if defined(QGC_HAS_GST_D3D12_GPU_PATH)
128 if (gst_is_d3d12_memory(mem0)) {
130 return buildOrFallback(std::make_unique<GstD3D12VideoBuffer>(sample, info, format));
134#if defined(QGC_HAS_GST_IOSURFACE_GPU_PATH)
136 if (mem0->allocator && g_strcmp0(mem0->allocator->mem_type,
"AppleCoreVideoMemory") == 0) {
138 return buildOrFallback(std::make_unique<GstIOSurfaceVideoBuffer>(sample, info, format));
142#if defined(QGC_HAS_GST_AHARDWAREBUFFER_GPU_PATH)
143 if (ahbEglDisplay != EGL_NO_DISPLAY && gst_is_ahardware_buffer_memory(mem0)) {
146 format.setPixelFormat(QVideoFrameFormat::Format_SamplerExternalOES);
147 return buildOrFallback(std::make_unique<GstAHardwareBufferVideoBuffer>(sample, info, format, ahbEglDisplay));
152 static QSet<QString> s_seen;
154 const QString memType = mem0->allocator
155 ? QString::fromUtf8(mem0->allocator->mem_type)
156 : QStringLiteral(
"<no-allocator>");
157 QMutexLocker lock(&s_mtx);
158 if (!s_seen.contains(memType)) {
159 s_seen.insert(memType);
160 qCDebug(GstHwBufFactoryLog) <<
"no zero-copy path for memory type"
161 << memType <<
"— falling back to CPU memcpy";