26#if G_BYTE_ORDER == G_LITTLE_ENDIAN
27 constexpr DRMFormat argb_fourcc = DRMFormat::ARGB8888;
28 constexpr DRMFormat rgba_fourcc = DRMFormat::ABGR8888;
29 constexpr DRMFormat rgb_fourcc = DRMFormat::BGR888;
30 constexpr DRMFormat rg_fourcc = DRMFormat::GR88;
32 constexpr DRMFormat argb_fourcc = DRMFormat::BGRA8888;
33 constexpr DRMFormat rgba_fourcc = DRMFormat::RGBA8888;
34 constexpr DRMFormat rgb_fourcc = DRMFormat::RGB888;
35 constexpr DRMFormat rg_fourcc = DRMFormat::RG88;
39 case GST_VIDEO_FORMAT_RGB16:
40 case GST_VIDEO_FORMAT_BGR16:
41 return DRMFormat::RGB565;
43 case GST_VIDEO_FORMAT_RGB:
44 case GST_VIDEO_FORMAT_BGR:
47 case GST_VIDEO_FORMAT_BGRx:
48 case GST_VIDEO_FORMAT_BGRA:
51 case GST_VIDEO_FORMAT_AYUV:
53 return DRMFormat::AYUV;
55 case GST_VIDEO_FORMAT_RGBx:
56 case GST_VIDEO_FORMAT_RGBA:
57 case GST_VIDEO_FORMAT_ARGB:
58 case GST_VIDEO_FORMAT_xRGB:
59 case GST_VIDEO_FORMAT_ABGR:
60 case GST_VIDEO_FORMAT_xBGR:
63 case GST_VIDEO_FORMAT_GRAY8:
66 case GST_VIDEO_FORMAT_YUY2:
67 return DRMFormat::YUYV;
69 case GST_VIDEO_FORMAT_UYVY:
70 return DRMFormat::UYVY;
72 case GST_VIDEO_FORMAT_GRAY16_LE:
73 case GST_VIDEO_FORMAT_GRAY16_BE:
75 return DRMFormat::R16;
78 case GST_VIDEO_FORMAT_NV12:
80 return DRMFormat::NV12;
82 case GST_VIDEO_FORMAT_NV21:
84 return DRMFormat::NV21;
85 return plane == 0 ? DRMFormat::R8 : rg_fourcc;
87 case GST_VIDEO_FORMAT_I420:
89 return DRMFormat::YUV420;
91 case GST_VIDEO_FORMAT_YV12:
93 return DRMFormat::YVU420;
95 case GST_VIDEO_FORMAT_Y41B:
97 return DRMFormat::YUV411;
99 case GST_VIDEO_FORMAT_Y42B:
101 return DRMFormat::YUV422;
103 case GST_VIDEO_FORMAT_Y444:
105 return DRMFormat::YUV444;
106 return DRMFormat::R8;
108 case GST_VIDEO_FORMAT_BGR10A2_LE:
109 return DRMFormat::BGRA1010102;
111 case GST_VIDEO_FORMAT_P010_10LE:
112 case GST_VIDEO_FORMAT_P010_10BE:
114 return DRMFormat::P010;
115 return plane == 0 ? DRMFormat::R16 : DRMFormat::RG1616;
134QGstDmaBufVideoBuffer::create(QGstBufferHandle buffer,
const QGstVideoInfo &videoInfo,
135 const QVideoFrameFormat &frameFormat)
137 using namespace QtMultimediaPrivate;
139 if (!buffer.isValid())
143 if (!gst_is_dmabuf_memory(gst_buffer_peek_memory(gstBuffer, 0)))
146 const GstVideoInfo &gstVideoInfo = videoInfo.gstVideoInfo;
147 if (!gstVideoInfo.finfo)
150 const GstVideoMeta *videoMeta = gst_buffer_get_video_meta(gstBuffer);
151 GstVideoFormat format = videoMeta ? videoMeta->format : GST_VIDEO_INFO_FORMAT(&gstVideoInfo);
152 if (format == GST_VIDEO_FORMAT_UNKNOWN)
153 format = GST_VIDEO_INFO_FORMAT(&gstVideoInfo);
155 const int nPlanes = videoMeta ? videoMeta->n_planes : GST_VIDEO_INFO_N_PLANES(&gstVideoInfo);
156 const int nMemoryBlocks = gst_buffer_n_memory(gstBuffer);
157 if (nPlanes < 1 || nPlanes > 4 || (nMemoryBlocks != 1 && nMemoryBlocks != nPlanes))
160 const QVideoFrameFormat::PixelFormat pixelFormat = frameFormat.pixelFormat();
161 const auto *desc = QVideoTextureHelper::textureDescription(pixelFormat);
162 if (!desc || desc->nplanes != nPlanes)
165 static const bool singleEGLImageEnv =
166 qEnvironmentVariableIntValue(
"QT_GSTREAMER_FORCE_SINGLE_EGLIMAGE") != 0;
167 const bool singleEGLImage =
168 QVideoTextureHelper::forceGlTextureExternalOesIsSet() || singleEGLImageEnv;
170 std::array<DmaBufPlane, 4> planes;
171 std::array<
int, 4> fds{ -1, -1, -1, -1 };
172 for (
int i = 0; i < nMemoryBlocks && i < 4; ++i)
173 fds[i] = gst_dmabuf_memory_get_fd(gst_buffer_peek_memory(gstBuffer, i));
175 const DRMModifier modifier = videoInfo.dmaDrmModifier ? DRMModifier{ *videoInfo.dmaDrmModifier }
176 : DmaBufFormatModifierInvalid;
178 for (
int plane = 0; plane < nPlanes; ++plane) {
179 const std::optional<DRMFormat> fourcc =
180 fourccFromGstVideoFormat(format, plane, singleEGLImage);
182 qCWarning(qLcGstDmaBufVideoBuffer)
183 <<
"Unsupported format for DMABuf:" << gst_video_format_to_string(format)
184 <<
"plane:" << plane <<
"singleEGLImage:" << singleEGLImage;
188 const int fd = (plane < nMemoryBlocks && fds[plane] >= 0) ? fds[plane] : fds[0];
192 planes[plane].fd = fd;
194 if (nPlanes == nMemoryBlocks) {
195 planes[plane].offset = 0;
196 }
else if (videoMeta) {
197 planes[plane].offset = videoMeta->offset[plane];
199 planes[plane].offset = GST_VIDEO_INFO_PLANE_OFFSET(&gstVideoInfo, plane);
202 planes[plane].pitch = videoMeta->stride[plane];
204 planes[plane].pitch = GST_VIDEO_INFO_PLANE_STRIDE(&gstVideoInfo, plane);
205 planes[plane].drmFormat = *fourcc;
206 planes[plane].modifier = modifier;
209 const DmaBufImportMode importMode =
210 singleEGLImage ? DmaBufImportMode::SingleImage : DmaBufImportMode::PerPlane;
211 return std::unique_ptr<QGstDmaBufVideoBuffer>(
212 new QGstDmaBufVideoBuffer(QSpan<
const DmaBufPlane>(planes.data(), nPlanes), importMode,
213 std::move(buffer), pixelFormat, frameFormat.frameSize()));