4#include <QtFFmpegMediaPluginImpl/private/qffmpegmediaintegration_p.h>
6#include <QtFFmpegMediaPluginImpl/private/qffmpegaudiodecoder_p.h>
7#include <QtFFmpegMediaPluginImpl/private/qffmpegaudioinput_p.h>
8#include <QtFFmpegMediaPluginImpl/private/qffmpegconverter_p.h>
9#include <QtFFmpegMediaPluginImpl/private/qffmpegimagecapture_p.h>
10#include <QtFFmpegMediaPluginImpl/private/qffmpegmediacapturesession_p.h>
11#include <QtFFmpegMediaPluginImpl/private/qffmpegmediaformatinfo_p.h>
12#include <QtFFmpegMediaPluginImpl/private/qffmpegmediaplayer_p.h>
13#include <QtFFmpegMediaPluginImpl/private/qffmpegmediarecorder_p.h>
14#include <QtFFmpegMediaPluginImpl/private/qffmpegresampler_p.h>
15#include <QtFFmpegMediaPluginImpl/private/qffmpegvideosink_p.h>
16#include <QtFFmpegMediaPluginImpl/private/qgrabwindowsurfacecapture_p.h>
18#include <QtMultimedia/private/qplatformmediaplugin_p.h>
19#include <QtMultimedia/qcameradevice.h>
22#include <QtFFmpegMediaPluginImpl/private/qcgcapturablewindows_p.h>
23#include <QtFFmpegMediaPluginImpl/private/qcgwindowcapture_p.h>
24#include <QtFFmpegMediaPluginImpl/private/qavfscreencapture_p.h>
28#include <QtFFmpegMediaPluginImpl/private/qavfcamerafactory_p.h>
29#include <QtMultimedia/private/qavfvideodevices_p.h>
33# include <QtMultimedia/private/qwindowsresampler_p.h>
34# include <QtMultimedia/private/qwindowsvideodevices_p.h>
35# include "qwindowscamera_p.h"
36# include "qffmpegscreencapture_dxgi_p.h"
37# include "qwincapturablewindows_p.h"
38# include "qgdiwindowcapture_p.h"
42#include <QtFFmpegMediaPluginImpl/private/qandroidcamera_p.h>
43#include <QtFFmpegMediaPluginImpl/private/qandroidimagecapture_p.h>
44#include <QtFFmpegMediaPluginImpl/private/qandroidscreencapture_p.h>
45#include <QtFFmpegMediaPluginImpl/private/qandroidvideodevices_p.h>
48# include <libavutil/log.h>
49# include <libavcodec/jni.h>
53#if QT_CONFIG(linux_v4l)
54#include "qv4l2camera_p.h"
55#include "qv4l2cameradevices_p.h"
58#if QT_CONFIG(cpp_winrt)
59#include "qffmpegwindowcapture_uwp_p.h"
63#include "qx11surfacecapture_p.h"
64#include "qx11capturablewindows_p.h"
67#if QT_CONFIG(pipewire_screencapture)
68# include <QtMultimedia/private/qpipewire_screencapture_p.h>
72#include "qeglfsscreencapture_p.h"
75#include <QtCore/qloggingcategory.h>
90 return av_log_default_callback(ptr, level, fmt, vl);
93 if (level < 0 || level > av_log_get_level())
96 QString message = QStringLiteral(
"FFmpeg log: %1").arg(QString::vasprintf(fmt, vl));
97 if (message.endsWith(u"\n"))
100 if (level == AV_LOG_DEBUG || level == AV_LOG_TRACE)
102 else if (level == AV_LOG_VERBOSE || level == AV_LOG_INFO)
104 else if (level == AV_LOG_WARNING)
105 qWarning() << message;
106 else if (level == AV_LOG_ERROR || level == AV_LOG_FATAL || level == AV_LOG_PANIC)
107 qCritical() << message;
112 if (qEnvironmentVariableIsSet(
"QT_FFMPEG_DEBUG")) {
113 av_log_set_level(AV_LOG_DEBUG);
117 av_log_set_callback(&qffmpegLogCallback);
122 if (backend == u"grabwindow")
123 return new QGrabWindowSurfaceCapture(QPlatformSurfaceCapture::ScreenSource{});
126 if (backend == u"eglfs")
127 return new QEglfsScreenCapture;
131 if (backend == u"x11")
132 return new QX11SurfaceCapture(QPlatformSurfaceCapture::ScreenSource{});
133#elif defined(Q_OS_WINDOWS)
134 if (backend == u"dxgi")
135 return new QFFmpegScreenCaptureDxgi;
136#elif defined(Q_OS_MACOS)
137 if (backend == u"avf")
138 return new QAVFScreenCapture;
145 if (backend == u"grabwindow")
146 return new QGrabWindowSurfaceCapture(QPlatformSurfaceCapture::WindowSource{});
149 if (backend == u"x11")
150 return new QX11SurfaceCapture(QPlatformSurfaceCapture::WindowSource{});
151#elif defined(Q_OS_WINDOWS)
152 if (backend == u"gdi")
153 return new QGdiWindowCapture;
154#if QT_CONFIG(cpp_winrt)
155 if (backend == u"uwp")
156 return new QFFmpegWindowCaptureUwp;
158#elif defined(Q_OS_MACOS)
159 if (backend == u"cg")
160 return new QCGWindowCapture;
165QFFmpegMediaIntegration::QFFmpegMediaIntegration()
166 : QPlatformMediaIntegration(QLatin1String(
"ffmpeg"))
170 qCInfo(qLcFFmpeg) <<
"Using Qt multimedia with FFmpeg version" << av_version_info()
173 qCDebug(qLcFFmpeg) <<
"Available HW decoding frameworks:";
174 for (
auto type : QFFmpeg::HWAccel::decodingDeviceTypes())
175 qCDebug(qLcFFmpeg) <<
" " << av_hwdevice_get_type_name(type);
177 qCDebug(qLcFFmpeg) <<
"Available HW encoding frameworks:";
178 for (
auto type : QFFmpeg::HWAccel::encodingDeviceTypes())
179 qCDebug(qLcFFmpeg) <<
" " << av_hwdevice_get_type_name(type);
182q23::expected<QPlatformAudioDecoder *, QString>
183QFFmpegMediaIntegration::createAudioDecoder(QAudioDecoder *decoder)
185 return new QFFmpegAudioDecoder(decoder);
188q23::expected<std::unique_ptr<QPlatformAudioResampler>, QString>
189QFFmpegMediaIntegration::createAudioResampler(
const QAudioFormat &inputFormat,
190 const QAudioFormat &outputFormat)
192 auto ffmpegResampler = QFFmpegResampler::createFromInputFormat(inputFormat, outputFormat);
194 return ffmpegResampler;
197 auto windowsResampler = std::make_unique<QWindowsResampler>();
198 if (windowsResampler->setup(inputFormat, outputFormat))
199 return std::move(windowsResampler);
203 return q23::unexpected{ notAvailable };
206q23::expected<QPlatformMediaCaptureSession *, QString>
207QFFmpegMediaIntegration::createCaptureSession()
209 return new QFFmpegMediaCaptureSession();
212q23::expected<QPlatformMediaPlayer *, QString>
213QFFmpegMediaIntegration::createPlayer(QMediaPlayer *player)
215 return new QFFmpegMediaPlayer(player);
218q23::expected<QPlatformCamera *, QString> QFFmpegMediaIntegration::createCamera(QCamera *camera)
222 return QFFmpeg::makeQAvfCamera(*camera).release();
223#elif defined(Q_OS_ANDROID)
224 return new QFFmpeg::QAndroidCamera(camera);
225#elif QT_CONFIG(linux_v4l)
226 return new QV4L2Camera(camera);
227#elif defined(Q_OS_WINDOWS)
228 return new QWindowsCamera(camera);
231 return q23::unexpected{ notAvailable };
235QPlatformSurfaceCapture *QFFmpegMediaIntegration::createScreenCapture(QScreenCapture *)
237 static const QString screenCaptureBackend =
238 QString::fromLocal8Bit(qgetenv(
"QT_SCREEN_CAPTURE_BACKEND")).toLower();
240 if (!screenCaptureBackend.isEmpty()) {
241 if (
auto screenCapture = createScreenCaptureByBackend(screenCaptureBackend))
242 return screenCapture;
244 qWarning() <<
"Not supported QT_SCREEN_CAPTURE_BACKEND:" << screenCaptureBackend;
248 if (QX11SurfaceCapture::isSupported())
249 return new QX11SurfaceCapture(QPlatformSurfaceCapture::ScreenSource{});
252#if QT_CONFIG(pipewire_screencapture)
253 if (QtPipeWire::QPipeWireCapture::isSupported())
254 return new QtPipeWire::QPipeWireCapture(QPlatformSurfaceCapture::ScreenSource{});
258 if (QEglfsScreenCapture::isSupported())
259 return new QEglfsScreenCapture;
262#if defined(Q_OS_WINDOWS)
263 return new QFFmpegScreenCaptureDxgi;
264#elif defined(Q_OS_MACOS)
265 return new QAVFScreenCapture;
266#elif defined(Q_OS_ANDROID)
267 return new QAndroidScreenCapture;
269 return new QGrabWindowSurfaceCapture(QPlatformSurfaceCapture::ScreenSource{});
273QPlatformSurfaceCapture *QFFmpegMediaIntegration::createWindowCapture(QWindowCapture *)
275 static const QString windowCaptureBackend =
276 QString::fromLocal8Bit(qgetenv(
"QT_WINDOW_CAPTURE_BACKEND")).toLower();
278 if (!windowCaptureBackend.isEmpty()) {
279 if (
auto windowCapture = createWindowCaptureByBackend(windowCaptureBackend))
280 return windowCapture;
282 qWarning() <<
"Not supported QT_WINDOW_CAPTURE_BACKEND:" << windowCaptureBackend;
286 if (QX11SurfaceCapture::isSupported())
287 return new QX11SurfaceCapture(QPlatformSurfaceCapture::WindowSource{});
290#if defined(Q_OS_WINDOWS)
291# if QT_CONFIG(cpp_winrt)
292 if (QFFmpegWindowCaptureUwp::isSupported())
293 return new QFFmpegWindowCaptureUwp;
296 return new QGdiWindowCapture;
297#elif defined(Q_OS_MACOS)
298 return new QCGWindowCapture;
300 return new QGrabWindowSurfaceCapture(QPlatformSurfaceCapture::WindowSource{});
304q23::expected<QPlatformMediaRecorder *, QString>
305QFFmpegMediaIntegration::createRecorder(QMediaRecorder *recorder)
307 return new QFFmpegMediaRecorder(recorder);
310q23::expected<QPlatformImageCapture *, QString>
311QFFmpegMediaIntegration::createImageCapture(QImageCapture *imageCapture)
313#if defined(Q_OS_ANDROID)
314 return new QFFmpeg::QAndroidImageCapture(imageCapture);
316 return new QFFmpegImageCapture(imageCapture);
320q23::expected<QPlatformVideoSink *, QString>
321QFFmpegMediaIntegration::createVideoSink(QVideoSink *sink)
323 return new QFFmpegVideoSink(sink);
326q23::expected<QPlatformAudioInput *, QString>
327QFFmpegMediaIntegration::createAudioInput(QAudioInput *input)
329 return new QFFmpegAudioInput(input);
332QVideoFrame QFFmpegMediaIntegration::convertVideoFrame(QVideoFrame &srcFrame,
333 const QVideoFrameFormat &destFormat)
335 return convertFrame(srcFrame, destFormat);
338QPlatformMediaFormatInfo *QFFmpegMediaIntegration::createFormatInfo()
340 return new QFFmpegMediaFormatInfo;
343QPlatformVideoDevices *QFFmpegMediaIntegration::createVideoDevices()
345#if defined(Q_OS_ANDROID)
346 return new QAndroidVideoDevices(
this);
347#elif QT_CONFIG(linux_v4l)
348 return new QV4L2CameraDevices(
this);
349#elif defined Q_OS_DARWIN
350 return new QAVFVideoDevices(
352 &QFFmpeg::isCVFormatSupported);
353#elif defined(Q_OS_WINDOWS)
354 return new QWindowsVideoDevices(
this);
360QPlatformCapturableWindows *QFFmpegMediaIntegration::createCapturableWindows()
363 if (QX11SurfaceCapture::isSupported())
364 return new QX11CapturableWindows;
365#elif defined Q_OS_MACOS
366 return new QCGCapturableWindows;
367#elif defined(Q_OS_WINDOWS)
368 return new QWinCapturableWindows;
375Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,
void * )
377 static bool initialized =
false;
379 return JNI_VERSION_1_6;
384 if (vm->GetEnv(&environment, JNI_VERSION_1_6))
388 if (av_jni_set_java_vm(vm,
nullptr))
391 if (!QFFmpeg::QAndroidCamera::registerNativeMethods()
392 ||!QAndroidScreenCapture::registerNativeMethods()) {
396 return JNI_VERSION_1_6;
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")