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;
120void rankDownPlugin(GstRegistry *reg,
const char *name)
122 QGstPluginFeatureHandle pluginFeature{
123 gst_registry_lookup_feature(reg, name),
124 QGstPluginFeatureHandle::HasRef,
127 gst_plugin_feature_set_rank(pluginFeature.get(), GST_RANK_PRIMARY - 1);
131constexpr auto vaapiPluginNames = {
132 "vaapidecodebin",
"vaapih264dec",
"vaapih264enc",
"vaapih265dec",
133 "vaapijpegdec",
"vaapijpegenc",
"vaapimpeg2dec",
"vaapipostproc",
134 "vaapisink",
"vaapivp8dec",
"vaapivp9dec",
138constexpr auto vaPluginNames = {
139 "vaav1dec",
"vacompositor",
"vadeinterlace",
"vah264dec",
"vah264enc",
"vah265dec",
140 "vajpegdec",
"vampeg2dec",
"vapostproc",
"vavp8dec",
"vavp9dec",
144constexpr auto nvcodecPluginNames = {
145 "cudaconvert",
"cudaconvertscale",
"cudadownload",
"cudaipcsink",
"cudaipcsrc",
146 "cudascale",
"cudaupload",
"nvautogpuh264enc",
"nvautogpuh265enc",
"nvav1dec",
147 "nvcudah264enc",
"nvcudah265enc",
"nvd3d11h264enc",
"nvd3d11h265enc",
"nvh264dec",
148 "nvh264enc",
"nvh265dec",
"nvh265enc",
"nvjpegdec",
"nvjpegenc",
149 "nvmpeg2videodec",
"nvmpeg4videodec",
"nvmpegvideodec",
"nvvp8dec",
"nvvp9dec",
157 gst_init(
nullptr,
nullptr);
159 const QGString version{ gst_version_string() };
160 qCInfo(lcGstreamer) <<
"Using Qt multimedia with GStreamer version:" << version.asStringView();
162 GstRegistry *reg = gst_registry_get();
164 if constexpr (!GST_CHECK_VERSION(1, 22, 0)) {
165 for (
const char *name : vaapiPluginNames)
166 rankDownPlugin(reg, name);
169 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_VA")) {
170 for (
const char *name : vaPluginNames)
171 rankDownPlugin(reg, name);
174 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DISABLE_NVCODEC")) {
175 for (
const char *name : nvcodecPluginNames)
176 rankDownPlugin(reg, name);
188 if (qEnvironmentVariableIsSet(
"QT_GSTREAMER_DEINIT"))
199 return new QGstreamerVideoDevices(
this);
209 return QGstreamerAudioDecoder::create(decoder);
214 return QGstreamerMediaCaptureSession::create();
219 return QGstreamerMediaPlayer::create(player);
225 QGstElement element = std::exchange(pendingCameraElement, {});
230 return QGstreamerCamera::create(camera);
240 return QGstreamerImageCapture::create(imageCapture);
250 return QGstreamerAudioInput::create(q);
255 return QGstreamerAudioOutput::create(q);
260 const auto devices = videoDevices();
261 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.
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)