4#include <qgstreamerintegration_p.h>
5#include <qgstreamerformatinfo_p.h>
6#include <qgstreamervideodevices_p.h>
7#include <audio/qgstreameraudiodevice_p.h>
8#include <audio/qgstreameraudiodecoder_p.h>
9#include <common/qgstreameraudioinput_p.h>
10#include <common/qgstreameraudiooutput_p.h>
11#include <common/qgstreamermediaplayer_p.h>
12#include <common/qgstreamervideosink_p.h>
13#include <mediacapture/qgstreamercamera_p.h>
14#include <mediacapture/qgstreamerimagecapture_p.h>
15#include <mediacapture/qgstreamermediacapturesession_p.h>
16#include <mediacapture/qgstreamermediarecorder_p.h>
17#include <uri_handler/qgstreamer_qiodevice_handler_p.h>
18#include <uri_handler/qgstreamer_qrc_handler_p.h>
20#include <QtCore/qloggingcategory.h>
21#include <QtMultimedia/private/qmediaplayer_p.h>
22#include <QtMultimedia/private/qmediacapturesession_p.h>
23#include <QtMultimedia/private/qcameradevice_p.h>
24#include <QtMultimedia/private/qvideoframe_p.h>
28static_assert(GST_CHECK_VERSION(1, 20, 0),
"Minimum required GStreamer version is 1.20");
37 const QByteArray &gstreamerPipeline)
39 return qMakeCustomGStreamerAudioInput(gstreamerPipeline);
43 const QByteArray &gstreamerPipeline)
45 return qMakeCustomGStreamerAudioOutput(gstreamerPipeline);
49 const QByteArray &gstreamerPipeline, QObject *parent)
51 QCameraDevicePrivate *info =
new QCameraDevicePrivate;
52 info->id = gstreamerPipeline;
53 QCameraDevice device = info->create();
56 auto guard = qScopeGuard([] {
60 return new QCamera(device, parent);
67 QCameraDevicePrivate *info =
new QCameraDevicePrivate;
68 info->id =
"Custom Camera from GstElement";
69 QCameraDevice device = info->create();
71 pendingCameraElement = QGstElement{
73 QGstElement::NeedsRef,
77 auto guard = qScopeGuard([] {
82 return new QCamera(device, parent);
87 auto *priv =
reinterpret_cast<QMediaPlayerPrivate *>(QMediaPlayerPrivate::get(player));
92 return gstreamerPlayer ? gstreamerPlayer
->pipeline().pipeline() :
nullptr;
98 auto *priv = QMediaCaptureSessionPrivate::get(session);
102 QGstreamerMediaCaptureSession *gstreamerCapture =
103 dynamic_cast<QGstreamerMediaCaptureSession *>(priv->captureSession.get());
104 return gstreamerCapture ? gstreamerCapture
->pipeline().pipeline() :
nullptr;
109 QHwVideoBuffer *hwBuffer = QVideoFramePrivate::hwBuffer(frame);
112 QGstVideoBuffer *gstBuffer =
dynamic_cast<QGstVideoBuffer *>(hwBuffer);
113 return gstBuffer ? gstBuffer->gstBuffer() :
nullptr;
117 GstBuffer *buffer,
const GstVideoInfo &videoInfo)
120 return QVideoFrame();
124 return qCreateFrameFromGstBuffer(QGstBufferHandle{ buffer, QGstBufferHandle::NeedsRef },
129 GstBuffer *buffer,
const GstVideoInfoDmaDrm &videoInfoDmaDrm)
133 Q_UNUSED(videoInfoDmaDrm);
134 qWarning() << QStringLiteral(
"GstVideoInfoDmaDrm unsupported, minimum GStreamer version required: 1.24");
135 return QVideoFrame();
138 return QVideoFrame();
140 QGstVideoInfo qtVideoInfo{ { }, videoInfoDmaDrm.drm_modifier };
141 if (!gst_video_info_dma_drm_to_video_info(&videoInfoDmaDrm, &qtVideoInfo.gstVideoInfo))
142 qWarning() <<
"Failed to create QGstVideoInfo from GstVideoInfoDmaDrm";
144 return qCreateFrameFromGstBuffer(QGstBufferHandle{ buffer, QGstBufferHandle::NeedsRef },
153void rankDownPlugin(GstRegistry *reg,
const char *name)
155 QGstPluginFeatureHandle pluginFeature{
156 gst_registry_lookup_feature(reg, name),
157 QGstPluginFeatureHandle::HasRef,
160 gst_plugin_feature_set_rank(pluginFeature.get(), GST_RANK_PRIMARY - 1);
164constexpr auto vaapiPluginNames = {
165 "vaapidecodebin",
"vaapih264dec",
"vaapih264enc",
"vaapih265dec",
166 "vaapijpegdec",
"vaapijpegenc",
"vaapimpeg2dec",
"vaapipostproc",
167 "vaapisink",
"vaapivp8dec",
"vaapivp9dec",
171constexpr auto vaPluginNames = {
172 "vaav1dec",
"vacompositor",
"vadeinterlace",
"vah264dec",
"vah264enc",
"vah265dec",
173 "vajpegdec",
"vampeg2dec",
"vapostproc",
"vavp8dec",
"vavp9dec",
177constexpr auto nvcodecPluginNames = {
178 "cudaconvert",
"cudaconvertscale",
"cudadownload",
"cudaipcsink",
"cudaipcsrc",
179 "cudascale",
"cudaupload",
"nvautogpuh264enc",
"nvautogpuh265enc",
"nvav1dec",
180 "nvcudah264enc",
"nvcudah265enc",
"nvd3d11h264enc",
"nvd3d11h265enc",
"nvh264dec",
181 "nvh264enc",
"nvh265dec",
"nvh265enc",
"nvjpegdec",
"nvjpegenc",
182 "nvmpeg2videodec",
"nvmpeg4videodec",
"nvmpegvideodec",
"nvvp8dec",
"nvvp9dec",
190 gst_init(
nullptr,
nullptr);
192 const QGString version{ gst_version_string() };
193 qCInfo(lcGstreamer) <<
"Using Qt multimedia with GStreamer version:" << version.asStringView();
195 GstRegistry *reg = gst_registry_get();
197 if constexpr (!GST_CHECK_VERSION(1, 22, 0)) {
198 for (
const char *name : vaapiPluginNames)
199 rankDownPlugin(reg, name);
202 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_VA")) {
203 for (
const char *name : vaPluginNames)
204 rankDownPlugin(reg, name);
207 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_NVCODEC")) {
208 for (
const char *name : nvcodecPluginNames)
209 rankDownPlugin(reg, name);
221 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DEINIT"))
232 return new QGstreamerVideoDevices(
this);
242 return QGstreamerAudioDecoder::create(decoder);
247 return QGstreamerMediaCaptureSession::create();
252 return QGstreamerMediaPlayer::create(player);
258 QGstElement element = std::exchange(pendingCameraElement, {});
263 return QGstreamerCamera::create(camera);
273 return QGstreamerImageCapture::create(imageCapture);
283 return QGstreamerAudioInput::create(q);
288 return QGstreamerAudioOutput::create(q);
293 const auto devices = videoDevices();
294 return devices ?
static_cast<QGstreamerVideoDevices *>(devices)->videoDevice(id) :
nullptr;
q23::expected< QPlatformCamera *, QString > createCamera(QCamera *) override
QPlatformVideoDevices * createVideoDevices() override
QPlatformMediaFormatInfo * createFormatInfo() override
q23::expected< QPlatformAudioOutput *, QString > createAudioOutput(QAudioOutput *) override
q23::expected< QPlatformVideoSink *, QString > createVideoSink(QVideoSink *sink) override
QGStreamerPlatformSpecificInterfaceImplementation m_platformSpecificImplementation
QAbstractPlatformSpecificInterface * platformSpecificInterface() override
~QGstreamerIntegration() override
q23::expected< QPlatformMediaCaptureSession *, QString > createCaptureSession() override
q23::expected< QPlatformMediaPlayer *, QString > createPlayer(QMediaPlayer *player) override
q23::expected< QPlatformMediaRecorder *, QString > createRecorder(QMediaRecorder *) override
const QGstreamerFormatInfo * gstFormatsInfo()
q23::expected< QPlatformAudioDecoder *, QString > createAudioDecoder(QAudioDecoder *decoder) override
q23::expected< QPlatformImageCapture *, QString > createImageCapture(QImageCapture *) override
GstDevice * videoDevice(const QByteArray &id)
q23::expected< QPlatformAudioInput *, QString > createAudioInput(QAudioInput *) override
Combined button and popup list for selecting options.
#define QT_GSTREAMER_SUPPORTS_GST_VIDEO_FORMAT_DMA_DRM
void qGstRegisterQIODeviceHandler(GstPlugin *plugin)
QT_BEGIN_NAMESPACE void qGstRegisterQRCHandler(GstPlugin *plugin)
static bool inCustomCameraConstruction
static QGstElement pendingCameraElement
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)