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>
27static_assert(GST_CHECK_VERSION(1, 20, 0),
"Minimum required GStreamer version is 1.20");
36 const QByteArray &gstreamerPipeline)
38 return qMakeCustomGStreamerAudioInput(gstreamerPipeline);
42 const QByteArray &gstreamerPipeline)
44 return qMakeCustomGStreamerAudioOutput(gstreamerPipeline);
48 const QByteArray &gstreamerPipeline, QObject *parent)
50 QCameraDevicePrivate *info =
new QCameraDevicePrivate;
51 info->id = gstreamerPipeline;
52 QCameraDevice device = info->create();
55 auto guard = qScopeGuard([] {
59 return new QCamera(device, parent);
66 QCameraDevicePrivate *info =
new QCameraDevicePrivate;
67 info->id =
"Custom Camera from GstElement";
68 QCameraDevice device = info->create();
70 pendingCameraElement = QGstElement{
72 QGstElement::NeedsRef,
76 auto guard = qScopeGuard([] {
81 return new QCamera(device, parent);
86 auto *priv =
reinterpret_cast<QMediaPlayerPrivate *>(QMediaPlayerPrivate::get(player));
91 return gstreamerPlayer ? gstreamerPlayer
->pipeline().pipeline() :
nullptr;
97 auto *priv = QMediaCaptureSessionPrivate::get(session);
101 QGstreamerMediaCaptureSession *gstreamerCapture =
102 dynamic_cast<QGstreamerMediaCaptureSession *>(priv->captureSession.get());
103 return gstreamerCapture ? gstreamerCapture
->pipeline().pipeline() :
nullptr;
110void rankDownPlugin(GstRegistry *reg,
const char *name)
112 QGstPluginFeatureHandle pluginFeature{
113 gst_registry_lookup_feature(reg, name),
114 QGstPluginFeatureHandle::HasRef,
117 gst_plugin_feature_set_rank(pluginFeature.get(), GST_RANK_PRIMARY - 1);
121constexpr auto vaapiPluginNames = {
122 "vaapidecodebin",
"vaapih264dec",
"vaapih264enc",
"vaapih265dec",
123 "vaapijpegdec",
"vaapijpegenc",
"vaapimpeg2dec",
"vaapipostproc",
124 "vaapisink",
"vaapivp8dec",
"vaapivp9dec",
128constexpr auto vaPluginNames = {
129 "vaav1dec",
"vacompositor",
"vadeinterlace",
"vah264dec",
"vah264enc",
"vah265dec",
130 "vajpegdec",
"vampeg2dec",
"vapostproc",
"vavp8dec",
"vavp9dec",
134constexpr auto nvcodecPluginNames = {
135 "cudaconvert",
"cudaconvertscale",
"cudadownload",
"cudaipcsink",
"cudaipcsrc",
136 "cudascale",
"cudaupload",
"nvautogpuh264enc",
"nvautogpuh265enc",
"nvav1dec",
137 "nvcudah264enc",
"nvcudah265enc",
"nvd3d11h264enc",
"nvd3d11h265enc",
"nvh264dec",
138 "nvh264enc",
"nvh265dec",
"nvh265enc",
"nvjpegdec",
"nvjpegenc",
139 "nvmpeg2videodec",
"nvmpeg4videodec",
"nvmpegvideodec",
"nvvp8dec",
"nvvp9dec",
147 gst_init(
nullptr,
nullptr);
149 const QGString version{ gst_version_string() };
150 qCInfo(lcGstreamer) <<
"Using Qt multimedia with GStreamer version:" << version.asStringView();
152 GstRegistry *reg = gst_registry_get();
154 if constexpr (!GST_CHECK_VERSION(1, 22, 0)) {
155 for (
const char *name : vaapiPluginNames)
156 rankDownPlugin(reg, name);
159 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_VA")) {
160 for (
const char *name : vaPluginNames)
161 rankDownPlugin(reg, name);
164 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_NVCODEC")) {
165 for (
const char *name : nvcodecPluginNames)
166 rankDownPlugin(reg, name);
178 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DEINIT"))
189 return new QGstreamerVideoDevices(
this);
199 return QGstreamerAudioDecoder::create(decoder);
204 return QGstreamerMediaCaptureSession::create();
209 return QGstreamerMediaPlayer::create(player);
215 QGstElement element = std::exchange(pendingCameraElement, {});
220 return QGstreamerCamera::create(camera);
230 return QGstreamerImageCapture::create(imageCapture);
240 return QGstreamerAudioInput::create(q);
245 return QGstreamerAudioOutput::create(q);
250 const auto devices = videoDevices();
251 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
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
void qGstRegisterQIODeviceHandler(GstPlugin *plugin)
void qGstRegisterQRCHandler(GstPlugin *plugin)
static thread_local bool inCustomCameraConstruction
static thread_local QGstElement pendingCameraElement