Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qffmpegmediaintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtMultimedia/private/qplatformmediaplugin_p.h>
5#include <qcameradevice.h>
13#include "qffmpegaudioinput_p.h"
15#include "qffmpegresampler_p.h"
17#include "qffmpegconverter_p.h"
18
19#ifdef Q_OS_MACOS
20#include <VideoToolbox/VideoToolbox.h>
21
23#include "qcgwindowcapture_p.h"
24#include "qavfscreencapture_p.h"
25#endif
26
27#ifdef Q_OS_DARWIN
28#include "qavfcamera_p.h"
29
30#elif defined(Q_OS_WINDOWS)
31#include "qwindowscamera_p.h"
35#include "qgdiwindowcapture_p.h"
36#endif
37
38#ifdef Q_OS_ANDROID
39# include "jni.h"
41# include "qandroidcamera_p.h"
43extern "C" {
44# include <libavutil/log.h>
45# include <libavcodec/jni.h>
46}
47#endif
48
49#if QT_CONFIG(linux_v4l)
50#include "qv4l2camera_p.h"
52#endif
53
54#if QT_CONFIG(cpp_winrt)
56#endif
57
58#if QT_CONFIG(xlib)
61#endif
62
63#if QT_CONFIG(pipewire)
64#include "qpipewirecapture_p.h"
65#endif
66
67#if QT_CONFIG(eglfs)
69#endif
70
72
74{
77
78public:
82
84 {
85 if (name == u"ffmpeg")
86 return new QFFmpegMediaIntegration;
87 return nullptr;
88 }
89};
90
91bool thread_local FFmpegLogsEnabledInThread = true;
92static bool UseCustomFFmpegLogger = false;
93
94static void qffmpegLogCallback(void *ptr, int level, const char *fmt, va_list vl)
95{
97 return;
98
100 return av_log_default_callback(ptr, level, fmt, vl);
101
102 // filter logs above the chosen level and AV_LOG_QUIET (negative level)
103 if (level < 0 || level > av_log_get_level())
104 return;
105
106 QString message = QStringLiteral("FFmpeg log: %1").arg(QString::vasprintf(fmt, vl));
107 if (message.endsWith("\n"))
108 message.removeLast();
109
110 if (level == AV_LOG_DEBUG || level == AV_LOG_TRACE)
111 qDebug() << message;
112 else if (level == AV_LOG_VERBOSE || level == AV_LOG_INFO)
113 qInfo() << message;
114 else if (level == AV_LOG_WARNING)
115 qWarning() << message;
116 else if (level == AV_LOG_ERROR || level == AV_LOG_FATAL || level == AV_LOG_PANIC)
117 qCritical() << message;
118}
119
120static void setupFFmpegLogger()
121{
122 if (qEnvironmentVariableIsSet("QT_FFMPEG_DEBUG")) {
123 av_log_set_level(AV_LOG_DEBUG);
125 }
126
127 av_log_set_callback(&qffmpegLogCallback);
128}
129
131{
132 if (backend == u"grabwindow")
134
135#if QT_CONFIG(eglfs)
136 if (backend == u"eglfs")
137 return new QEglfsScreenCapture;
138#endif
139
140#if QT_CONFIG(xlib)
141 if (backend == u"x11")
143#elif defined(Q_OS_WINDOWS)
144 if (backend == u"dxgi")
145 return new QFFmpegScreenCaptureDxgi;
146#elif defined(Q_OS_MACOS)
147 if (backend == u"avf")
148 return new QAVFScreenCapture;
149#endif
150 return nullptr;
151}
152
154{
155 if (backend == u"grabwindow")
157
158#if QT_CONFIG(xlib)
159 if (backend == u"x11")
161#elif defined(Q_OS_WINDOWS)
162 if (backend == u"gdi")
163 return new QGdiWindowCapture;
164#if QT_CONFIG(cpp_winrt)
165 if (backend == u"uwp")
166 return new QFFmpegWindowCaptureUwp;
167#endif
168#elif defined(Q_OS_MACOS)
169 if (backend == u"cg")
170 return new QCGWindowCapture;
171#endif
172 return nullptr;
173}
174
177{
179
180#ifndef QT_NO_DEBUG
181 qDebug() << "Available HW decoding frameworks:";
183 qDebug() << " " << av_hwdevice_get_type_name(type);
184
185 qDebug() << "Available HW encoding frameworks:";
187 qDebug() << " " << av_hwdevice_get_type_name(type);
188#endif
189}
190
191QMaybe<QPlatformAudioDecoder *> QFFmpegMediaIntegration::createAudioDecoder(QAudioDecoder *decoder)
192{
193 return new QFFmpegAudioDecoder(decoder);
194}
195
196QMaybe<std::unique_ptr<QPlatformAudioResampler>>
198 const QAudioFormat &outputFormat)
199{
200 return { std::make_unique<QFFmpegResampler>(inputFormat, outputFormat) };
201}
202
203QMaybe<QPlatformMediaCaptureSession *> QFFmpegMediaIntegration::createCaptureSession()
204{
205 return new QFFmpegMediaCaptureSession();
206}
207
209{
210 return new QFFmpegMediaPlayer(player);
211}
212
214{
215#ifdef Q_OS_DARWIN
216 return new QAVFCamera(camera);
217#elif defined(Q_OS_ANDROID)
218 return new QAndroidCamera(camera);
219#elif QT_CONFIG(linux_v4l)
220 return new QV4L2Camera(camera);
221#elif defined(Q_OS_WINDOWS)
222 return new QWindowsCamera(camera);
223#else
225 return nullptr;//new QFFmpegCamera(camera);
226#endif
227}
228
230{
231 static const QString screenCaptureBackend = qgetenv("QT_SCREEN_CAPTURE_BACKEND").toLower();
232
233 if (!screenCaptureBackend.isEmpty()) {
234 if (auto screenCapture = createScreenCaptureByBackend(screenCaptureBackend))
235 return screenCapture;
236
237 qWarning() << "Not supported QT_SCREEN_CAPTURE_BACKEND:" << screenCaptureBackend;
238 }
239
240#if QT_CONFIG(xlib)
243#endif
244
245#if QT_CONFIG(pipewire)
248#endif
249
250#if QT_CONFIG(eglfs)
252 return new QEglfsScreenCapture;
253#endif
254
255#if defined(Q_OS_WINDOWS)
256 return new QFFmpegScreenCaptureDxgi;
257#elif defined(Q_OS_MACOS) // TODO: probably use it for iOS as well
258 return new QAVFScreenCapture;
259#else
261#endif
262}
263
265{
266 static const QString windowCaptureBackend = qgetenv("QT_WINDOW_CAPTURE_BACKEND").toLower();
267
268 if (!windowCaptureBackend.isEmpty()) {
269 if (auto windowCapture = createWindowCaptureByBackend(windowCaptureBackend))
270 return windowCapture;
271
272 qWarning() << "Not supported QT_WINDOW_CAPTURE_BACKEND:" << windowCaptureBackend;
273 }
274
275#if QT_CONFIG(xlib)
278#endif
279
280#if defined(Q_OS_WINDOWS)
281# if QT_CONFIG(cpp_winrt)
283 return new QFFmpegWindowCaptureUwp;
284# endif
285
286 return new QGdiWindowCapture;
287#elif defined(Q_OS_MACOS) // TODO: probably use it for iOS as well
288 return new QCGWindowCapture;
289#else
291#endif
292}
293
295{
296 return new QFFmpegMediaRecorder(recorder);
297}
298
300{
301#if defined(Q_OS_ANDROID)
303#else
305#endif
306}
307
309{
310 return new QFFmpegVideoSink(sink);
311}
312
314{
315 return new QFFmpegAudioInput(input);
316}
317
319 const QVideoFrameFormat &destFormat)
320{
321 return convertFrame(srcFrame, destFormat);
322}
323
328
330{
331#if defined(Q_OS_ANDROID)
332 return new QAndroidVideoDevices(this);
333#elif QT_CONFIG(linux_v4l)
334 return new QV4L2CameraDevices(this);
335#elif defined Q_OS_DARWIN
336 return new QAVFVideoDevices(this);
337#elif defined(Q_OS_WINDOWS)
338 return new QWindowsVideoDevices(this);
339#else
340 return nullptr;
341#endif
342}
343
345{
346#if QT_CONFIG(xlib)
348 return new QX11CapturableWindows;
349#elif defined Q_OS_MACOS
350 return new QCGCapturableWindows;
351#elif defined(Q_OS_WINDOWS)
352 return new QWinCapturableWindows;
353#endif
354 return nullptr;
355}
356
357#ifdef Q_OS_ANDROID
358
359Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
360{
361 static bool initialized = false;
362 if (initialized)
363 return JNI_VERSION_1_6;
364 initialized = true;
365
367 void *environment;
368 if (vm->GetEnv(&environment, JNI_VERSION_1_6))
369 return JNI_ERR;
370
371 // setting our javavm into ffmpeg.
372 if (av_jni_set_java_vm(vm, nullptr))
373 return JNI_ERR;
374
376 return JNI_ERR;
377
378 return JNI_VERSION_1_6;
379}
380#endif
381
383
384#include "qffmpegmediaintegration.moc"
QMediaPlayer player
Definition audio.cpp:213
static bool registerNativeMethods()
The QAudioDecoder class implements decoding audio.
The QAudioFormat class stores audio stream parameter information.
\qmltype AudioInput \instantiates QAudioInput
Definition qaudioinput.h:19
The QCamera class provides interface for system camera devices.
Definition qcamera.h:28
\inmodule QtMultimedia
QMaybe< std::unique_ptr< QPlatformAudioResampler > > createAudioResampler(const QAudioFormat &inputFormat, const QAudioFormat &outputFormat) override
QPlatformMediaFormatInfo * createFormatInfo() override
QPlatformSurfaceCapture * createScreenCapture(QScreenCapture *) override
QMaybe< QPlatformMediaPlayer * > createPlayer(QMediaPlayer *player) override
QMaybe< QPlatformVideoSink * > createVideoSink(QVideoSink *sink) override
QVideoFrame convertVideoFrame(QVideoFrame &srcFrame, const QVideoFrameFormat &destFormat) override
QMaybe< QPlatformAudioInput * > createAudioInput(QAudioInput *input) override
QMaybe< QPlatformAudioDecoder * > createAudioDecoder(QAudioDecoder *decoder) override
QMaybe< QPlatformImageCapture * > createImageCapture(QImageCapture *) override
QMaybe< QPlatformMediaRecorder * > createRecorder(QMediaRecorder *) override
QMaybe< QPlatformMediaCaptureSession * > createCaptureSession() override
QMaybe< QPlatformCamera * > createCamera(QCamera *) override
QPlatformVideoDevices * createVideoDevices() override
QPlatformCapturableWindows * createCapturableWindows() override
QPlatformSurfaceCapture * createWindowCapture(QWindowCapture *) override
QPlatformMediaIntegration * create(const QString &name) override
static const std::vector< AVHWDeviceType > & decodingDeviceTypes()
static const std::vector< AVHWDeviceType > & encodingDeviceTypes()
\inmodule QtMultimedia
The QMediaPlayer class allows the playing of a media files.
\inmodule QtMultimedia
\inmodule QtMultimedia
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition qstring.cpp:7368
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
The QVideoSink class represents a generic sink for video data.
Definition qvideosink.h:22
\inmodule QtMultimedia
QMediaRecorder * recorder
Definition camera.cpp:20
QCamera * camera
Definition camera.cpp:19
QImageCapture * imageCapture
Definition camera.cpp:21
Combined button and popup list for selecting options.
#define Q_DECL_EXPORT
QVideoFrame convertFrame(QVideoFrame &src, const QVideoFrameFormat &dstFormat)
static bool UseCustomFFmpegLogger
static QPlatformSurfaceCapture * createScreenCaptureByBackend(QString backend)
static QPlatformSurfaceCapture * createWindowCaptureByBackend(QString backend)
bool thread_local FFmpegLogsEnabledInThread
static void qffmpegLogCallback(void *ptr, int level, const char *fmt, va_list vl)
static void setupFFmpegLogger()
QT_END_NAMESPACE JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
#define qCritical
Definition qlogging.h:168
#define qInfo
Definition qlogging.h:166
#define qDebug
[1]
Definition qlogging.h:165
#define qWarning
Definition qlogging.h:167
static ControlElement< T > * ptr(QWidget *widget)
GLenum GLuint GLint level
GLenum type
GLuint GLsizei const GLchar * message
GLuint name
GLsizei GLenum GLboolean sink
GLenum GLenum GLenum input
#define QPlatformMediaPlugin_iid
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
#define Q_OBJECT
#define Q_PLUGIN_METADATA(x)
#define Q_UNUSED(x)
QVideoFrameFormat::PixelFormat fmt