summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/multimedia/spectrum/app/engine.cpp6
-rw-r--r--examples/multimedia/video/qmlvideo/main.cpp21
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.pro4
-rw-r--r--examples/multimedia/video/qmlvideofx/main.cpp21
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.pro4
-rw-r--r--examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp4
-rw-r--r--src/gsttools/gstvideoconnector.c16
-rw-r--r--src/gsttools/qgstappsrc.cpp2
-rw-r--r--src/gsttools/qgstbufferpoolinterface_p.h4
-rw-r--r--src/gsttools/qgstcodecsinfo.cpp4
-rw-r--r--src/gsttools/qgstreameraudioinputselector.cpp15
-rw-r--r--src/gsttools/qgstreamerbufferprobe.cpp4
-rw-r--r--src/gsttools/qgstreamerbushelper.cpp10
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp110
-rw-r--r--src/gsttools/qgstreamervideooverlay.cpp46
-rw-r--r--src/gsttools/qgstutils.cpp60
-rw-r--r--src/gsttools/qgstvideorenderersink.cpp26
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp18
-rw-r--r--src/imports/multimedia/Video.qml19
-rw-r--r--src/imports/multimedia/multimedia.cpp6
-rw-r--r--src/imports/multimedia/plugins.qmltypes36
-rw-r--r--src/imports/multimedia/qdeclarativeaudio.cpp59
-rw-r--r--src/imports/multimedia/qdeclarativeaudio_p.h6
-rw-r--r--src/imports/multimedia/qdeclarativecamera.cpp17
-rw-r--r--src/imports/multimedia/qdeclarativecamera_p.h5
-rw-r--r--src/multimedia/audio/qsamplecache_p.cpp2
-rw-r--r--src/multimedia/camera/qcamera.cpp11
-rw-r--r--src/multimedia/camera/qcamera.h3
-rw-r--r--src/multimedia/controls/qaudiodecodercontrol.cpp1
-rw-r--r--src/multimedia/controls/qaudioencodersettingscontrol.cpp1
-rw-r--r--src/multimedia/controls/qaudioinputselectorcontrol.cpp1
-rw-r--r--src/multimedia/controls/qaudiooutputselectorcontrol.cpp1
-rw-r--r--src/multimedia/controls/qaudiorolecontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameracapturebufferformatcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameracapturedestinationcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameracontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameraexposurecontrol.cpp1
-rw-r--r--src/multimedia/controls/qcamerafeedbackcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameraflashcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcamerafocuscontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameraimagecapturecontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameraimageprocessingcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcamerainfocontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameralockscontrol.cpp1
-rw-r--r--src/multimedia/controls/qcameraviewfindersettingscontrol.cpp1
-rw-r--r--src/multimedia/controls/qcamerazoomcontrol.cpp1
-rw-r--r--src/multimedia/controls/qcustomaudiorolecontrol.cpp1
-rw-r--r--src/multimedia/controls/qimageencodercontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediaaudioprobecontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediaavailabilitycontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediacontainercontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediagaplessplaybackcontrol.cpp1
-rw-r--r--src/multimedia/controls/qmedianetworkaccesscontrol.cpp3
-rw-r--r--src/multimedia/controls/qmedianetworkaccesscontrol.h12
-rw-r--r--src/multimedia/controls/qmediaplayercontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediarecordercontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediastreamscontrol.cpp1
-rw-r--r--src/multimedia/controls/qmediavideoprobecontrol.cpp1
-rw-r--r--src/multimedia/controls/qmetadatareadercontrol.cpp1
-rw-r--r--src/multimedia/controls/qmetadatawritercontrol.cpp1
-rw-r--r--src/multimedia/controls/qradiodatacontrol.cpp1
-rw-r--r--src/multimedia/controls/qradiotunercontrol.cpp2
-rw-r--r--src/multimedia/controls/qvideodeviceselectorcontrol.cpp1
-rw-r--r--src/multimedia/controls/qvideoencodersettingscontrol.cpp1
-rw-r--r--src/multimedia/controls/qvideorenderercontrol.cpp1
-rw-r--r--src/multimedia/controls/qvideowindowcontrol.cpp1
-rw-r--r--src/multimedia/doc/snippets/multimedia-snippets/multimedia-snippets.pro3
-rw-r--r--src/multimedia/doc/snippets/multimedia-snippets/multiple-videooutputs.qml (renamed from src/multimedia/video/qvideoframe_p.h)48
-rw-r--r--src/multimedia/doc/snippets/multimedia-snippets/video.cpp23
-rw-r--r--src/multimedia/playback/qmediaplayer.cpp31
-rw-r--r--src/multimedia/playback/qmediaplayer.h25
-rw-r--r--src/multimedia/playback/qplaylistfileparser.cpp2
-rw-r--r--src/multimedia/qmediacontrol.cpp1
-rw-r--r--src/multimedia/qmediapluginloader.cpp2
-rw-r--r--src/multimedia/qmediaservice.cpp1
-rw-r--r--src/multimedia/qmediaserviceprovider.cpp6
-rw-r--r--src/multimedia/video/qvideoframe.cpp8
-rw-r--r--src/multimedia/video/qvideoframe.h2
-rw-r--r--src/multimedia/video/qvideosurfaces.cpp103
-rw-r--r--src/multimedia/video/qvideosurfaces_p.h77
-rw-r--r--src/multimedia/video/video.pri7
-rw-r--r--src/multimediawidgets/qgraphicsvideoitem.cpp20
-rw-r--r--src/multimediawidgets/qgraphicsvideoitem.h2
-rw-r--r--src/multimediawidgets/qpaintervideosurface.cpp109
-rw-r--r--src/multimediawidgets/qpaintervideosurface_p.h13
-rw-r--r--src/multimediawidgets/qvideowidget.cpp65
-rw-r--r--src/multimediawidgets/qvideowidget.h3
-rw-r--r--src/multimediawidgets/qvideowidget_p.h49
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.cpp3
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp8
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp2
-rw-r--r--src/plugins/avfoundation/camera/avfcameraservice.h2
-rw-r--r--src/plugins/avfoundation/camera/avfcameraservice.mm23
-rw-r--r--src/plugins/avfoundation/camera/avfcamerasession.h3
-rw-r--r--src/plugins/avfoundation/camera/avfcamerasession.mm33
-rw-r--r--src/plugins/avfoundation/camera/avfcamerawindowcontrol.h129
-rw-r--r--src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm262
-rw-r--r--src/plugins/avfoundation/camera/avfimagecapturecontrol.mm3
-rw-r--r--src/plugins/avfoundation/camera/camera.pro6
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h6
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm112
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm6
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp3
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinzoom.cpp32
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinzoom.h4
-rw-r--r--src/plugins/m3u/qm3uhandler.cpp2
-rw-r--r--src/qtmultimediaquicktools/qdeclarativevideooutput.cpp40
-rw-r--r--src/qtmultimediaquicktools/qdeclarativevideooutput_p.h4
-rw-r--r--src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp7
-rw-r--r--tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp15
-rw-r--r--tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp41
-rw-r--r--tests/auto/integration/qmediaplayerbackend/BLACKLIST1
-rw-r--r--tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp48
-rw-r--r--tests/auto/unit/qabstractvideosurface/tst_qabstractvideosurface.cpp18
-rw-r--r--tests/auto/unit/qcamera/tst_qcamera.cpp2
-rw-r--r--tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro2
-rw-r--r--tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp49
-rw-r--r--tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp43
-rw-r--r--tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.cpp6
-rw-r--r--tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.cpp6
-rw-r--r--tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp113
-rw-r--r--tests/auto/unit/qvideoframe/tst_qvideoframe.cpp171
-rw-r--r--tests/auto/unit/qvideowidget/tst_qvideowidget.cpp29
124 files changed, 1940 insertions, 487 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 35dba5489..b3c7403c2 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST
-MODULE_VERSION = 5.14.2
+MODULE_VERSION = 5.15.0
diff --git a/examples/multimedia/spectrum/app/engine.cpp b/examples/multimedia/spectrum/app/engine.cpp
index fd977785b..d188259dc 100644
--- a/examples/multimedia/spectrum/app/engine.cpp
+++ b/examples/multimedia/spectrum/app/engine.cpp
@@ -569,15 +569,17 @@ bool Engine::selectFormat()
sampleRatesList += m_audioInputDevice.supportedSampleRates();
sampleRatesList += m_audioOutputDevice.supportedSampleRates();
- sampleRatesList = sampleRatesList.toSet().toList(); // remove duplicates
std::sort(sampleRatesList.begin(), sampleRatesList.end());
+ const auto uniqueRatesEnd = std::unique(sampleRatesList.begin(), sampleRatesList.end());
+ sampleRatesList.erase(uniqueRatesEnd, sampleRatesList.end());
ENGINE_DEBUG << "Engine::initialize frequenciesList" << sampleRatesList;
QList<int> channelsList;
channelsList += m_audioInputDevice.supportedChannelCounts();
channelsList += m_audioOutputDevice.supportedChannelCounts();
- channelsList = channelsList.toSet().toList();
std::sort(channelsList.begin(), channelsList.end());
+ const auto uniqueChannelsEnd = std::unique(channelsList.begin(), channelsList.end());
+ channelsList.erase(uniqueChannelsEnd, channelsList.end());
ENGINE_DEBUG << "Engine::initialize channelsList" << channelsList;
QAudioFormat format;
diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp
index e288c0ae4..01178acaa 100644
--- a/examples/multimedia/video/qmlvideo/main.cpp
+++ b/examples/multimedia/video/qmlvideo/main.cpp
@@ -62,6 +62,23 @@
#include "performancemonitordeclarative.h"
#endif
+#ifdef REQUEST_PERMISSIONS_ON_ANDROID
+#include <QtAndroid>
+
+bool requestStoragePermission() {
+ using namespace QtAndroid;
+
+ QString permission = QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE");
+ const QHash<QString, PermissionResult> results = requestPermissionsSync(QStringList({permission}));
+ if (!results.contains(permission) || results[permission] == PermissionResult::Denied) {
+ qWarning() << "Couldn't get permission: " << permission;
+ return false;
+ }
+
+ return true;
+}
+#endif
+
static const QString DefaultFileName1 = "";
static const QString DefaultFileName2 = "";
@@ -72,6 +89,10 @@ int main(int argc, char *argv[])
#ifdef PERFORMANCEMONITOR_SUPPORT
PerformanceMonitor::qmlRegisterTypes();
#endif
+#ifdef REQUEST_PERMISSIONS_ON_ANDROID
+ if (!requestStoragePermission())
+ return -1;
+#endif
QString source1, source2;
qreal volume = 0.5;
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.pro b/examples/multimedia/video/qmlvideo/qmlvideo.pro
index 022835f12..dbd3a42a1 100644
--- a/examples/multimedia/video/qmlvideo/qmlvideo.pro
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.pro
@@ -2,6 +2,10 @@ TEMPLATE = app
TARGET = qmlvideo
QT += quick multimedia
+android: qtHaveModule(androidextras) {
+ QT += androidextras
+ DEFINES += REQUEST_PERMISSIONS_ON_ANDROID
+}
LOCAL_SOURCES = main.cpp
LOCAL_HEADERS = trace.h
diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp
index 814c85368..ec547795f 100644
--- a/examples/multimedia/video/qmlvideofx/main.cpp
+++ b/examples/multimedia/video/qmlvideofx/main.cpp
@@ -61,6 +61,23 @@
#include "performancemonitordeclarative.h"
#endif
+#ifdef REQUEST_PERMISSIONS_ON_ANDROID
+#include <QtAndroid>
+
+bool requestStoragePermission() {
+ using namespace QtAndroid;
+
+ QString permission = QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE");
+ const QHash<QString, PermissionResult> results = requestPermissionsSync(QStringList({permission}));
+ if (!results.contains(permission) || results[permission] == PermissionResult::Denied) {
+ qWarning() << "Couldn't get permission: " << permission;
+ return false;
+ }
+
+ return true;
+}
+#endif
+
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
@@ -68,6 +85,10 @@ int main(int argc, char *argv[])
#ifdef PERFORMANCEMONITOR_SUPPORT
PerformanceMonitor::qmlRegisterTypes();
#endif
+#ifdef REQUEST_PERMISSIONS_ON_ANDROID
+ if (!requestStoragePermission())
+ return -1;
+#endif
QUrl fileName;
qreal volume = 0.5;
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro
index 097ad7516..07047aec8 100644
--- a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro
@@ -2,6 +2,10 @@ TEMPLATE = app
TARGET = qmlvideofx
QT += quick multimedia
+android: qtHaveModule(androidextras) {
+ QT += androidextras
+ DEFINES += REQUEST_PERMISSIONS_ON_ANDROID
+}
SOURCES += filereader.cpp main.cpp
HEADERS += filereader.h trace.h
diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp
index 1fdd1c7f7..2a9900c2b 100644
--- a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp
+++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp
@@ -55,7 +55,7 @@
#include <QVideoSurfaceFormat>
#if !defined(QT_NO_OPENGL)
-# include <QGLWidget>
+# include <QOpenGLWidget>
#endif
VideoPlayer::VideoPlayer(QWidget *parent)
@@ -71,7 +71,7 @@ VideoPlayer::VideoPlayer(QWidget *parent)
QGraphicsView *graphicsView = new QGraphicsView(scene);
#if !defined(QT_NO_OPENGL)
- graphicsView->setViewport(new QGLWidget);
+ graphicsView->setViewport(new QOpenGLWidget);
#endif
scene->addItem(videoItem);
diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c
index b85f5bdbe..7f88a89af 100644
--- a/src/gsttools/gstvideoconnector.c
+++ b/src/gsttools/gstvideoconnector.c
@@ -116,13 +116,13 @@ gst_video_connector_class_init (GstVideoConnectorClass * klass)
gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] =
g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL,
+ G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), nullptr, nullptr,
g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] =
g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
+ 0, nullptr, nullptr,
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
@@ -159,7 +159,7 @@ gst_video_connector_init (GstVideoConnector *element,
element->relinked = FALSE;
element->failedSignalEmited = FALSE;
gst_segment_init (&element->segment, GST_FORMAT_TIME);
- element->latest_buffer = NULL;
+ element->latest_buffer = nullptr;
}
static void
@@ -167,9 +167,9 @@ gst_video_connector_reset (GstVideoConnector * element)
{
element->relinked = FALSE;
element->failedSignalEmited = FALSE;
- if (element->latest_buffer != NULL) {
+ if (element->latest_buffer != nullptr) {
gst_buffer_unref (element->latest_buffer);
- element->latest_buffer = NULL;
+ element->latest_buffer = nullptr;
}
gst_segment_init (&element->segment, GST_FORMAT_UNDEFINED);
}
@@ -196,7 +196,7 @@ gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
if (!buf)
return GST_FLOW_ERROR;
- *buf = NULL;
+ *buf = nullptr;
gboolean isFailed = FALSE;
while (1) {
@@ -265,7 +265,7 @@ gst_video_connector_setcaps (GstPad *pad, GstCaps *caps)
/* forward-negotiate */
gboolean res = gst_pad_set_caps(element->srcpad, caps);
- gchar * debugmsg = NULL;
+ gchar * debugmsg = nullptr;
GST_DEBUG_OBJECT(element, "gst_video_connector_setcaps %s %i", debugmsg = gst_caps_to_string(caps), res);
if (debugmsg)
g_free(debugmsg);
@@ -407,7 +407,7 @@ gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
if (element->latest_buffer) {
gst_buffer_unref (element->latest_buffer);
- element->latest_buffer = NULL;
+ element->latest_buffer = nullptr;
}
element->latest_buffer = gst_buffer_ref(buf);
diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp
index d5c44ec08..f6ecd48be 100644
--- a/src/gsttools/qgstappsrc.cpp
+++ b/src/gsttools/qgstappsrc.cpp
@@ -69,7 +69,7 @@ bool QGstAppSrc::setup(GstElement* appsrc)
gst_object_ref(G_OBJECT(m_appSrc));
gst_app_src_set_callbacks(m_appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, (GDestroyNotify)&QGstAppSrc::destroy_notify);
- g_object_get(G_OBJECT(m_appSrc), "max-bytes", &m_maxBytes, NULL);
+ g_object_get(G_OBJECT(m_appSrc), "max-bytes", &m_maxBytes, nullptr);
if (m_sequential)
m_streamType = GST_APP_STREAM_TYPE_STREAM;
diff --git a/src/gsttools/qgstbufferpoolinterface_p.h b/src/gsttools/qgstbufferpoolinterface_p.h
index 45e573262..f5cbc35aa 100644
--- a/src/gsttools/qgstbufferpoolinterface_p.h
+++ b/src/gsttools/qgstbufferpoolinterface_p.h
@@ -79,7 +79,7 @@ public:
/*!
Build an QAbstractVideoBuffer instance from GstBuffer.
- Returns NULL if GstBuffer is not compatible with this buffer pool.
+ Returns nullptr if GstBuffer is not compatible with this buffer pool.
This method is called from gstreamer video sink thread.
*/
@@ -105,7 +105,7 @@ public:
/*!
Build an QAbstractVideoBuffer instance from compatible GstBuffer.
- Returns NULL if GstBuffer is not compatible with this buffer pool.
+ Returns nullptr if GstBuffer is not compatible with this buffer pool.
This method is called from gstreamer video sink thread.
*/
diff --git a/src/gsttools/qgstcodecsinfo.cpp b/src/gsttools/qgstcodecsinfo.cpp
index c6e61f824..2522ee19c 100644
--- a/src/gsttools/qgstcodecsinfo.cpp
+++ b/src/gsttools/qgstcodecsinfo.cpp
@@ -99,7 +99,7 @@ QStringList QGstCodecsInfo::codecOptions(const QString &codec) const
if (elementName.isEmpty())
return options;
- GstElement *element = gst_element_factory_make(elementName, NULL);
+ GstElement *element = gst_element_factory_make(elementName, nullptr);
if (element) {
guint numProperties;
GParamSpec **properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(element),
@@ -174,7 +174,7 @@ void QGstCodecsInfo::updateCodecs(ElementType elementType)
}
}
- GstCaps *newCaps = gst_caps_new_full(newStructure, NULL);
+ GstCaps *newCaps = gst_caps_new_full(newStructure, nullptr);
gchar *capsString = gst_caps_to_string(newCaps);
QString codec = QLatin1String(capsString);
diff --git a/src/gsttools/qgstreameraudioinputselector.cpp b/src/gsttools/qgstreameraudioinputselector.cpp
index 72d079cbc..3bf5538c2 100644
--- a/src/gsttools/qgstreameraudioinputselector.cpp
+++ b/src/gsttools/qgstreameraudioinputselector.cpp
@@ -124,24 +124,21 @@ void QGstreamerAudioInputSelector::updateAlsaDevices()
}
n = hints;
- while (*n != NULL) {
+ while (*n != nullptr) {
char *name = snd_device_name_get_hint(*n, "NAME");
char *descr = snd_device_name_get_hint(*n, "DESC");
char *io = snd_device_name_get_hint(*n, "IOID");
- if ((name != NULL) && (descr != NULL)) {
- if ( io == NULL || qstrcmp(io,"Input") == 0 ) {
+ if ((name != nullptr) && (descr != nullptr)) {
+ if (io == nullptr || qstrcmp(io, "Input") == 0) {
m_names.append(QLatin1String("alsa:")+QString::fromUtf8(name));
m_descriptions.append(QString::fromUtf8(descr));
}
}
- if (name != NULL)
- free(name);
- if (descr != NULL)
- free(descr);
- if (io != NULL)
- free(io);
+ free(name);
+ free(descr);
+ free(io);
n++;
}
snd_device_name_free_hint(hints);
diff --git a/src/gsttools/qgstreamerbufferprobe.cpp b/src/gsttools/qgstreamerbufferprobe.cpp
index d95de4c63..e2956eadd 100644
--- a/src/gsttools/qgstreamerbufferprobe.cpp
+++ b/src/gsttools/qgstreamerbufferprobe.cpp
@@ -70,11 +70,11 @@ void QGstreamerBufferProbe::addProbeToPad(GstPad *pad, bool downstream)
: GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
capsProbe,
this,
- NULL);
+ nullptr);
}
if (m_flags & ProbeBuffers) {
m_bufferProbeId = gst_pad_add_probe(
- pad, GST_PAD_PROBE_TYPE_BUFFER, bufferProbe, this, NULL);
+ pad, GST_PAD_PROBE_TYPE_BUFFER, bufferProbe, this, nullptr);
}
#else
Q_UNUSED(downstream);
diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp
index 5df046fde..1a4034eee 100644
--- a/src/gsttools/qgstreamerbushelper.cpp
+++ b/src/gsttools/qgstreamerbushelper.cpp
@@ -69,7 +69,7 @@ public:
connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval()));
m_intervalTimer->start();
} else {
- m_tag = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT, busCallback, this, NULL);
+ m_tag = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT, busCallback, this, nullptr);
}
}
@@ -186,27 +186,27 @@ QGstreamerBusHelper::~QGstreamerBusHelper()
void QGstreamerBusHelper::installMessageFilter(QObject *filter)
{
- QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+ auto syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
if (syncFilter) {
QMutexLocker lock(&d->filterMutex);
if (!d->syncFilters.contains(syncFilter))
d->syncFilters.append(syncFilter);
}
- QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+ auto busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
if (busFilter && !d->busFilters.contains(busFilter))
d->busFilters.append(busFilter);
}
void QGstreamerBusHelper::removeMessageFilter(QObject *filter)
{
- QGstreamerSyncMessageFilter *syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
+ auto syncFilter = qobject_cast<QGstreamerSyncMessageFilter*>(filter);
if (syncFilter) {
QMutexLocker lock(&d->filterMutex);
d->syncFilters.removeAll(syncFilter);
}
- QGstreamerBusMessageFilter *busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
+ auto busFilter = qobject_cast<QGstreamerBusMessageFilter*>(filter);
if (busFilter)
d->busFilters.removeAll(busFilter);
}
diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
index ed3f16c5f..c6d2df810 100644
--- a/src/gsttools/qgstreamerplayersession.cpp
+++ b/src/gsttools/qgstreamerplayersession.cpp
@@ -118,7 +118,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
void QGstreamerPlayerSession::initPlaybin()
{
- m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, NULL);
+ m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, nullptr);
if (m_playbin) {
//GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale,
//since those elements are included in the video output bin when necessary.
@@ -131,7 +131,7 @@ void QGstreamerPlayerSession::initPlaybin()
flags |= GST_PLAY_FLAG_NATIVE_VIDEO;
#endif
}
- g_object_set(G_OBJECT(m_playbin), "flags", flags, NULL);
+ g_object_set(G_OBJECT(m_playbin), "flags", flags, nullptr);
const QByteArray envAudioSink = qgetenv("QT_GSTREAMER_PLAYBIN_AUDIOSINK");
GstElement *audioSink = gst_element_factory_make(envAudioSink.isEmpty() ? "autoaudiosink" : envAudioSink, "audiosink");
@@ -144,7 +144,7 @@ void QGstreamerPlayerSession::initPlaybin()
if (m_volumeElement) {
m_audioSink = gst_bin_new("audio-output-bin");
- gst_bin_add_many(GST_BIN(m_audioSink), m_volumeElement, audioSink, NULL);
+ gst_bin_add_many(GST_BIN(m_audioSink), m_volumeElement, audioSink, nullptr);
gst_element_link(m_volumeElement, audioSink);
GstPad *pad = gst_element_get_static_pad(m_volumeElement, "sink");
@@ -156,13 +156,13 @@ void QGstreamerPlayerSession::initPlaybin()
}
}
- g_object_set(G_OBJECT(m_playbin), "audio-sink", m_audioSink, NULL);
+ g_object_set(G_OBJECT(m_playbin), "audio-sink", m_audioSink, nullptr);
addAudioBufferProbe();
}
}
#if GST_CHECK_VERSION(1,0,0)
- m_videoIdentity = gst_element_factory_make("identity", NULL); // floating ref
+ m_videoIdentity = gst_element_factory_make("identity", nullptr); // floating ref
#else
m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref
g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this);
@@ -172,8 +172,8 @@ void QGstreamerPlayerSession::initPlaybin()
qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace));
#endif
- m_nullVideoSink = gst_element_factory_make("fakesink", NULL);
- g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, NULL);
+ m_nullVideoSink = gst_element_factory_make("fakesink", nullptr);
+ g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, nullptr);
gst_object_ref(GST_OBJECT(m_nullVideoSink));
m_videoOutputBin = gst_bin_new("video-output-bin");
@@ -183,15 +183,15 @@ void QGstreamerPlayerSession::initPlaybin()
GstElement *videoOutputSink = m_videoIdentity;
#if QT_CONFIG(gstreamer_gl)
if (QGstUtils::useOpenGL()) {
- videoOutputSink = gst_element_factory_make("glupload", NULL);
- GstElement *colorConvert = gst_element_factory_make("glcolorconvert", NULL);
- gst_bin_add_many(GST_BIN(m_videoOutputBin), videoOutputSink, colorConvert, m_videoIdentity, m_nullVideoSink, NULL);
- gst_element_link_many(videoOutputSink, colorConvert, m_videoIdentity, NULL);
+ videoOutputSink = gst_element_factory_make("glupload", nullptr);
+ GstElement *colorConvert = gst_element_factory_make("glcolorconvert", nullptr);
+ gst_bin_add_many(GST_BIN(m_videoOutputBin), videoOutputSink, colorConvert, m_videoIdentity, m_nullVideoSink, nullptr);
+ gst_element_link_many(videoOutputSink, colorConvert, m_videoIdentity, nullptr);
} else {
- gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, NULL);
+ gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, nullptr);
}
#else
- gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, NULL);
+ gst_bin_add_many(GST_BIN(m_videoOutputBin), m_videoIdentity, m_nullVideoSink, nullptr);
#endif
gst_element_link(m_videoIdentity, m_nullVideoSink);
@@ -206,7 +206,7 @@ void QGstreamerPlayerSession::initPlaybin()
// Sort out messages
setBus(gst_element_get_bus(m_playbin));
- g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL);
+ g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, nullptr);
g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this);
g_signal_connect(G_OBJECT(m_playbin), "element-added", G_CALLBACK(handleElementAdded), this);
@@ -287,7 +287,7 @@ void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *o
return;
GstElement *appsrc;
- g_object_get(orig, "source", &appsrc, NULL);
+ g_object_get(orig, "source", &appsrc, nullptr);
if (!self->appsrc()->setup(appsrc))
qWarning()<<"Could not setup appsrc element";
@@ -314,7 +314,7 @@ void QGstreamerPlayerSession::loadFromStream(const QNetworkRequest &request, QIO
m_tags.clear();
emit tagsChanged();
- g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", NULL);
+ g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", nullptr);
if (!m_streamTypes.isEmpty()) {
m_streamProperties.clear();
@@ -346,7 +346,7 @@ void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request)
m_tags.clear();
emit tagsChanged();
- g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), NULL);
+ g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), nullptr);
if (!m_streamTypes.isEmpty()) {
m_streamProperties.clear();
@@ -497,7 +497,7 @@ void QGstreamerPlayerSession::setPlaybackRate(qreal rate)
gst_element_seek(m_pipeline, rate, GST_FORMAT_TIME,
GstSeekFlags(GST_SEEK_FLAG_FLUSH),
GST_SEEK_TYPE_NONE,0,
- GST_SEEK_TYPE_NONE,0 );
+ GST_SEEK_TYPE_END, 0);
}
emit playbackRateChanged(m_playbackRate);
}
@@ -547,13 +547,13 @@ int QGstreamerPlayerSession::activeStream(QMediaStreamsControl::StreamType strea
if (m_playbin) {
switch (streamType) {
case QMediaStreamsControl::AudioStream:
- g_object_get(G_OBJECT(m_playbin), "current-audio", &streamNumber, NULL);
+ g_object_get(G_OBJECT(m_playbin), "current-audio", &streamNumber, nullptr);
break;
case QMediaStreamsControl::VideoStream:
- g_object_get(G_OBJECT(m_playbin), "current-video", &streamNumber, NULL);
+ g_object_get(G_OBJECT(m_playbin), "current-video", &streamNumber, nullptr);
break;
case QMediaStreamsControl::SubPictureStream:
- g_object_get(G_OBJECT(m_playbin), "current-text", &streamNumber, NULL);
+ g_object_get(G_OBJECT(m_playbin), "current-text", &streamNumber, nullptr);
break;
default:
break;
@@ -578,13 +578,13 @@ void QGstreamerPlayerSession::setActiveStream(QMediaStreamsControl::StreamType s
if (m_playbin) {
switch (streamType) {
case QMediaStreamsControl::AudioStream:
- g_object_set(G_OBJECT(m_playbin), "current-audio", streamNumber, NULL);
+ g_object_set(G_OBJECT(m_playbin), "current-audio", streamNumber, nullptr);
break;
case QMediaStreamsControl::VideoStream:
- g_object_set(G_OBJECT(m_playbin), "current-video", streamNumber, NULL);
+ g_object_set(G_OBJECT(m_playbin), "current-video", streamNumber, nullptr);
break;
case QMediaStreamsControl::SubPictureStream:
- g_object_set(G_OBJECT(m_playbin), "current-text", streamNumber, NULL);
+ g_object_set(G_OBJECT(m_playbin), "current-text", streamNumber, nullptr);
break;
default:
break;
@@ -666,9 +666,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
}
}
- QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput);
-
- m_renderer = renderer;
+ m_renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput);
emit rendererChanged();
// No sense to continue if custom pipeline requested.
@@ -737,7 +735,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
qDebug() << "Failed to connect video output, inserting the colorspace element.";
#endif
gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
- linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL);
+ linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, nullptr);
}
#endif
@@ -746,7 +744,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) {
gboolean value = m_displayPrerolledFrame;
- g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, nullptr);
}
addVideoBufferProbe();
@@ -782,7 +780,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
//block pads, async to avoid locking in paused state
GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src");
#if GST_CHECK_VERSION(1,0,0)
- this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCKING), block_pad_cb, this, NULL);
+ this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCKING), block_pad_cb, this, nullptr);
#else
gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this);
#endif
@@ -815,7 +813,7 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
//pad is not blocked, it's possible to swap outputs only in the null state
qWarning() << "Pad is not blocked yet, could not switch video sink";
GstState identityElementState = GST_STATE_NULL;
- gst_element_get_state(m_videoIdentity, &identityElementState, NULL, GST_CLOCK_TIME_NONE);
+ gst_element_get_state(m_videoIdentity, &identityElementState, nullptr, GST_CLOCK_TIME_NONE);
if (identityElementState != GST_STATE_NULL) {
gst_object_unref(GST_OBJECT(srcPad));
return; //can't change vo yet, received async call from the previous change
@@ -873,7 +871,7 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
qDebug() << "Failed to connect video output, inserting the colorspace element.";
#endif
gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
- linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL);
+ linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, nullptr);
}
#endif
@@ -964,7 +962,7 @@ void QGstreamerPlayerSession::insertColorSpaceElement(GstElement *element, gpoin
gst_element_unlink(session->m_videoIdentity, session->m_videoSink);
gst_bin_add(GST_BIN(session->m_videoOutputBin), session->m_colorSpace);
- gst_element_link_many(session->m_videoIdentity, session->m_colorSpace, session->m_videoSink, NULL);
+ gst_element_link_many(session->m_videoIdentity, session->m_colorSpace, session->m_videoSink, nullptr);
GstState state = GST_STATE_VOID_PENDING;
@@ -1108,7 +1106,7 @@ void QGstreamerPlayerSession::setVolume(int volume)
m_volume = volume;
if (m_volumeElement)
- g_object_set(G_OBJECT(m_volumeElement), "volume", m_volume / 100.0, NULL);
+ g_object_set(G_OBJECT(m_volumeElement), "volume", m_volume / 100.0, nullptr);
emit volumeChanged(m_volume);
}
@@ -1123,7 +1121,7 @@ void QGstreamerPlayerSession::setMuted(bool muted)
m_muted = muted;
if (m_volumeElement)
- g_object_set(G_OBJECT(m_volumeElement), "mute", m_muted ? TRUE : FALSE, NULL);
+ g_object_set(G_OBJECT(m_volumeElement), "mute", m_muted ? TRUE : FALSE, nullptr);
emit mutedStateChanged(m_muted);
}
@@ -1455,9 +1453,9 @@ void QGstreamerPlayerSession::getStreamsInfo()
gint videoStreamsCount = 0;
gint textStreamsCount = 0;
- g_object_get(G_OBJECT(m_playbin), "n-audio", &audioStreamsCount, NULL);
- g_object_get(G_OBJECT(m_playbin), "n-video", &videoStreamsCount, NULL);
- g_object_get(G_OBJECT(m_playbin), "n-text", &textStreamsCount, NULL);
+ g_object_get(G_OBJECT(m_playbin), "n-audio", &audioStreamsCount, nullptr);
+ g_object_get(G_OBJECT(m_playbin), "n-video", &videoStreamsCount, nullptr);
+ g_object_get(G_OBJECT(m_playbin), "n-text", &textStreamsCount, nullptr);
haveAudio = audioStreamsCount > 0;
haveVideo = videoStreamsCount > 0;
@@ -1617,7 +1615,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
Q_UNUSED(p);
GstElement *source = 0;
- g_object_get(o, "source", &source, NULL);
+ g_object_get(o, "source", &source, nullptr);
if (source == 0)
return;
@@ -1634,7 +1632,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
// defined in extra-headers
if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "user-agent") != 0) {
g_object_set(G_OBJECT(source), "user-agent",
- self->m_request.rawHeader(userAgentString).constData(), NULL);
+ self->m_request.rawHeader(userAgentString).constData(), nullptr);
}
// The rest
@@ -1659,7 +1657,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
}
if (gst_structure_n_fields(extras) > 0)
- g_object_set(G_OBJECT(source), "extra-headers", extras, NULL);
+ g_object_set(G_OBJECT(source), "extra-headers", extras, nullptr);
gst_structure_free(extras);
}
@@ -1675,7 +1673,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
// Gst 0.10 -> microsecond
convertedTimeout *= 1000000;
#endif
- g_object_set(G_OBJECT(source), "timeout", convertedTimeout, NULL);
+ g_object_set(G_OBJECT(source), "timeout", convertedTimeout, nullptr);
self->m_sourceType = UDPSrc;
//The udpsrc is always a live source.
self->m_isLiveSource = true;
@@ -1684,26 +1682,26 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
const QString var = QLatin1String("udpsrc.caps");
if (query.hasQueryItem(var)) {
GstCaps *caps = gst_caps_from_string(query.queryItemValue(var).toLatin1().constData());
- g_object_set(G_OBJECT(source), "caps", caps, NULL);
+ g_object_set(G_OBJECT(source), "caps", caps, nullptr);
gst_caps_unref(caps);
}
} else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstSoupHTTPSrc") == 0) {
//souphttpsrc timeout unit = second
- g_object_set(G_OBJECT(source), "timeout", guint(timeout), NULL);
+ g_object_set(G_OBJECT(source), "timeout", guint(timeout), nullptr);
self->m_sourceType = SoupHTTPSrc;
//since gst_base_src_is_live is not reliable, so we check the source property directly
gboolean isLive = false;
- g_object_get(G_OBJECT(source), "is-live", &isLive, NULL);
+ g_object_get(G_OBJECT(source), "is-live", &isLive, nullptr);
self->m_isLiveSource = isLive;
} else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstMMSSrc") == 0) {
self->m_sourceType = MMSSrc;
self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source));
- g_object_set(G_OBJECT(source), "tcp-timeout", G_GUINT64_CONSTANT(timeout*1000000), NULL);
+ g_object_set(G_OBJECT(source), "tcp-timeout", G_GUINT64_CONSTANT(timeout*1000000), nullptr);
} else if (qstrcmp(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(source)), "GstRTSPSrc") == 0) {
//rtspsrc acts like a live source and will therefore only generate data in the PLAYING state.
self->m_sourceType = RTSPSrc;
self->m_isLiveSource = true;
- g_object_set(G_OBJECT(source), "buffer-mode", 1, NULL);
+ g_object_set(G_OBJECT(source), "buffer-mode", 1, nullptr);
} else {
self->m_sourceType = UnknownSrc;
self->m_isLiveSource = gst_base_src_is_live(GST_BASE_SRC(source));
@@ -1717,7 +1715,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
#endif
if (self->m_videoSink)
- g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, NULL);
+ g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, nullptr);
gst_object_unref(source);
}
@@ -1738,7 +1736,7 @@ void QGstreamerPlayerSession::handleVolumeChange(GObject *o, GParamSpec *p, gpoi
void QGstreamerPlayerSession::updateVolume()
{
double volume = 1.0;
- g_object_get(m_playbin, "volume", &volume, NULL);
+ g_object_get(m_playbin, "volume", &volume, nullptr);
if (m_volume != int(volume*100 + 0.5)) {
m_volume = int(volume*100 + 0.5);
@@ -1760,7 +1758,7 @@ void QGstreamerPlayerSession::handleMutedChange(GObject *o, GParamSpec *p, gpoin
void QGstreamerPlayerSession::updateMuted()
{
gboolean muted = FALSE;
- g_object_get(G_OBJECT(m_playbin), "mute", &muted, NULL);
+ g_object_get(G_OBJECT(m_playbin), "mute", &muted, nullptr);
if (m_muted != muted) {
m_muted = muted;
#ifdef DEBUG_PLAYBIN
@@ -1775,8 +1773,8 @@ static gboolean factory_can_src_any_caps (GstElementFactory *factory, const GstC
{
GList *templates;
- g_return_val_if_fail(factory != NULL, FALSE);
- g_return_val_if_fail(caps != NULL, FALSE);
+ g_return_val_if_fail(factory != nullptr, FALSE);
+ g_return_val_if_fail(caps != nullptr, FALSE);
templates = factory->staticpadtemplates;
@@ -1813,7 +1811,7 @@ GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bi
if (g_str_has_prefix(factoryName, "vaapi")) {
GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
#if GST_CHECK_VERSION(1,0,0)
- GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, NULL);
+ GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, nullptr);
#else
GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
#endif
@@ -1843,7 +1841,7 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
if (g_str_has_prefix(elementName, "queue2")) {
// Disable on-disk buffering.
- g_object_set(G_OBJECT(element), "temp-template", NULL, NULL);
+ g_object_set(G_OBJECT(element), "temp-template", nullptr, nullptr);
} else if (g_str_has_prefix(elementName, "uridecodebin") ||
#if GST_CHECK_VERSION(1,0,0)
g_str_has_prefix(elementName, "decodebin")) {
@@ -1851,7 +1849,7 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
g_str_has_prefix(elementName, "decodebin2")) {
if (g_str_has_prefix(elementName, "uridecodebin")) {
// Add video/x-surface (VAAPI) to default raw formats
- g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL);
+ g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), nullptr);
// listen for uridecodebin autoplug-select to skip VAAPI usage when the current
// video sink doesn't support it
g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
@@ -1894,7 +1892,7 @@ void QGstreamerPlayerSession::showPrerollFrames(bool enabled)
g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) {
gboolean value = enabled;
- g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, nullptr);
m_displayPrerolledFrame = enabled;
}
}
diff --git a/src/gsttools/qgstreamervideooverlay.cpp b/src/gsttools/qgstreamervideooverlay.cpp
index 6b862e475..d410be7d9 100644
--- a/src/gsttools/qgstreamervideooverlay.cpp
+++ b/src/gsttools/qgstreamervideooverlay.cpp
@@ -122,7 +122,7 @@ public:
{
int brightness = 0;
if (m_hasBrightness)
- g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, nullptr);
return brightness / 10;
}
@@ -131,7 +131,7 @@ public:
{
m_brightness = brightness;
if (m_hasBrightness)
- g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, nullptr);
return m_hasBrightness;
}
@@ -140,7 +140,7 @@ public:
{
int contrast = 0;
if (m_hasContrast)
- g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, nullptr);
return contrast / 10;
}
@@ -149,7 +149,7 @@ public:
{
m_contrast = contrast;
if (m_hasContrast)
- g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, nullptr);
return m_hasContrast;
}
@@ -158,7 +158,7 @@ public:
{
int hue = 0;
if (m_hasHue)
- g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "hue", &hue, nullptr);
return hue / 10;
}
@@ -167,7 +167,7 @@ public:
{
m_hue = hue;
if (m_hasHue)
- g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, nullptr);
return m_hasHue;
}
@@ -176,7 +176,7 @@ public:
{
int saturation = 0;
if (m_hasSaturation)
- g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, nullptr);
return saturation / 10;
}
@@ -185,7 +185,7 @@ public:
{
m_saturation = saturation;
if (m_hasSaturation)
- g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, nullptr);
return m_hasSaturation;
}
@@ -195,7 +195,7 @@ public:
Qt::AspectRatioMode mode = Qt::KeepAspectRatio;
if (m_hasForceAspectRatio) {
gboolean forceAR = false;
- g_object_get(G_OBJECT(m_videoSink), "force-aspect-ratio", &forceAR, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "force-aspect-ratio", &forceAR, nullptr);
if (!forceAR)
mode = Qt::IgnoreAspectRatio;
}
@@ -210,7 +210,7 @@ public:
g_object_set(G_OBJECT(m_videoSink),
"force-aspect-ratio",
(mode == Qt::KeepAspectRatio),
- (const char*)NULL);
+ nullptr);
}
}
@@ -245,7 +245,7 @@ public:
{
gfloat brightness = 0;
if (m_hasBrightness)
- g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, nullptr);
return brightness * 100; // [-1,1] -> [-100,100]
}
@@ -255,7 +255,7 @@ public:
m_brightness = brightness;
if (m_hasBrightness) {
gfloat v = brightness / 100.0; // [-100,100] -> [-1,1]
- g_object_set(G_OBJECT(m_videoSink), "brightness", v, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "brightness", v, nullptr);
}
return m_hasBrightness;
@@ -265,7 +265,7 @@ public:
{
gfloat contrast = 1;
if (m_hasContrast)
- g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, nullptr);
return (contrast - 1) * 100; // [0,2] -> [-100,100]
}
@@ -275,7 +275,7 @@ public:
m_contrast = contrast;
if (m_hasContrast) {
gfloat v = (contrast / 100.0) + 1; // [-100,100] -> [0,2]
- g_object_set(G_OBJECT(m_videoSink), "contrast", v, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "contrast", v, nullptr);
}
return m_hasContrast;
@@ -285,7 +285,7 @@ public:
{
gfloat hue = 0;
if (m_hasHue)
- g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "hue", &hue, nullptr);
return hue / 180 * 100; // [-180,180] -> [-100,100]
}
@@ -295,7 +295,7 @@ public:
m_hue = hue;
if (m_hasHue) {
gfloat v = hue / 100.0 * 180; // [-100,100] -> [-180,180]
- g_object_set(G_OBJECT(m_videoSink), "hue", v, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "hue", v, nullptr);
}
return m_hasHue;
@@ -305,7 +305,7 @@ public:
{
gfloat saturation = 1;
if (m_hasSaturation)
- g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, nullptr);
return (saturation - 1) * 100; // [0,2] -> [-100,100]
}
@@ -315,7 +315,7 @@ public:
m_saturation = saturation;
if (m_hasSaturation) {
gfloat v = (saturation / 100.0) + 1; // [-100,100] -> [0,2]
- g_object_set(G_OBJECT(m_videoSink), "saturation", v, NULL);
+ g_object_set(G_OBJECT(m_videoSink), "saturation", v, nullptr);
}
return m_hasSaturation;
@@ -350,7 +350,7 @@ static GstElement *findBestVideoSink()
continue;
#endif
if (platform == QLatin1String(elementMap[i].qtPlatform)
- && (choice = gst_element_factory_make(elementMap[i].gstreamerElement, NULL))) {
+ && (choice = gst_element_factory_make(elementMap[i].gstreamerElement, nullptr))) {
if (qt_gst_element_is_functioning(choice))
return choice;
@@ -363,13 +363,13 @@ static GstElement *findBestVideoSink()
// If none of the known video sinks are available, try to find one that implements the
// GstVideoOverlay interface and has autoplugging rank.
GList *list = qt_gst_video_sinks();
- for (GList *item = list; item != NULL; item = item->next) {
+ for (GList *item = list; item != nullptr; item = item->next) {
GstElementFactory *f = GST_ELEMENT_FACTORY(item->data);
if (!gst_element_factory_has_interface(f, QT_GSTREAMER_VIDEOOVERLAY_INTERFACE_NAME))
continue;
- if (GstElement *el = gst_element_factory_create(f, NULL)) {
+ if (GstElement *el = gst_element_factory_create(f, nullptr)) {
if (qt_gst_element_is_functioning(el)) {
choice = el;
break;
@@ -390,7 +390,7 @@ QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray
{
GstElement *sink = nullptr;
if (!elementName.isEmpty())
- sink = gst_element_factory_make(elementName.constData(), NULL);
+ sink = gst_element_factory_make(elementName.constData(), nullptr);
else
sink = findBestVideoSink();
@@ -567,7 +567,7 @@ void QGstreamerVideoOverlay::updateIsActive()
gboolean showPreroll = true;
if (m_sinkProperties->hasShowPrerollFrame())
- g_object_get(G_OBJECT(m_videoSink), "show-preroll-frame", &showPreroll, NULL);
+ g_object_get(G_OBJECT(m_videoSink), "show-preroll-frame", &showPreroll, nullptr);
bool newIsActive = (state == GST_STATE_PLAYING || (state == GST_STATE_PAUSED && showPreroll));
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
index f8a9d79c1..3f68244ba 100644
--- a/src/gsttools/qgstutils.cpp
+++ b/src/gsttools/qgstutils.cpp
@@ -424,7 +424,7 @@ GstCaps *QGstUtils::capsForAudioFormat(const QAudioFormat &format)
"format" , G_TYPE_STRING, gst_audio_format_to_string(qt_audioLookup[i].format),
"rate" , G_TYPE_INT , format.sampleRate(),
"channels", G_TYPE_INT , format.channelCount(),
- NULL);
+ nullptr);
}
return 0;
#else
@@ -432,29 +432,29 @@ GstCaps *QGstUtils::capsForAudioFormat(const QAudioFormat &format)
if (format.isValid()) {
if (format.sampleType() == QAudioFormat::SignedInt || format.sampleType() == QAudioFormat::UnSignedInt) {
- structure = gst_structure_new("audio/x-raw-int", NULL);
+ structure = gst_structure_new("audio/x-raw-int", nullptr);
} else if (format.sampleType() == QAudioFormat::Float) {
- structure = gst_structure_new("audio/x-raw-float", NULL);
+ structure = gst_structure_new("audio/x-raw-float", nullptr);
}
}
GstCaps *caps = 0;
if (structure) {
- gst_structure_set(structure, "rate", G_TYPE_INT, format.sampleRate(), NULL);
- gst_structure_set(structure, "channels", G_TYPE_INT, format.channelCount(), NULL);
- gst_structure_set(structure, "width", G_TYPE_INT, format.sampleSize(), NULL);
- gst_structure_set(structure, "depth", G_TYPE_INT, format.sampleSize(), NULL);
+ gst_structure_set(structure, "rate", G_TYPE_INT, format.sampleRate(), nullptr);
+ gst_structure_set(structure, "channels", G_TYPE_INT, format.channelCount(), nullptr);
+ gst_structure_set(structure, "width", G_TYPE_INT, format.sampleSize(), nullptr);
+ gst_structure_set(structure, "depth", G_TYPE_INT, format.sampleSize(), nullptr);
if (format.byteOrder() == QAudioFormat::LittleEndian)
- gst_structure_set(structure, "endianness", G_TYPE_INT, 1234, NULL);
+ gst_structure_set(structure, "endianness", G_TYPE_INT, 1234, nullptr);
else if (format.byteOrder() == QAudioFormat::BigEndian)
- gst_structure_set(structure, "endianness", G_TYPE_INT, 4321, NULL);
+ gst_structure_set(structure, "endianness", G_TYPE_INT, 4321, nullptr);
if (format.sampleType() == QAudioFormat::SignedInt)
- gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, TRUE, nullptr);
else if (format.sampleType() == QAudioFormat::UnSignedInt)
- gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, FALSE, NULL);
+ gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, FALSE, nullptr);
caps = gst_caps_new_empty();
Q_ASSERT(caps);
@@ -470,7 +470,7 @@ void QGstUtils::initializeGst()
static bool initialized = false;
if (!initialized) {
initialized = true;
- gst_init(NULL, NULL);
+ gst_init(nullptr, nullptr);
}
}
@@ -606,8 +606,8 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
// no-op
} else for (int i = 0; i < 2; ++i) {
gint orientation = 0;
- g_object_set(G_OBJECT(camera), "camera-device", i, NULL);
- g_object_get(G_OBJECT(camera), "sensor-mount-angle", &orientation, NULL);
+ g_object_set(G_OBJECT(camera), "camera-device", i, nullptr);
+ g_object_get(G_OBJECT(camera), "sensor-mount-angle", &orientation, nullptr);
devices[i].orientation = (720 - orientation) % 360;
}
@@ -807,7 +807,7 @@ QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFac
QSet<QString> supportedMimeTypes;
//enumerate supported mime types
- gst_init(NULL, NULL);
+ gst_init(nullptr, nullptr);
#if GST_CHECK_VERSION(1,0,0)
GstRegistry *registry = gst_registry_get();
@@ -829,7 +829,7 @@ QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFac
GList *orig_features = gst_registry_get_feature_list_by_plugin(
registry, gst_plugin_get_name(plugin));
for (GList *features = orig_features; features; features = g_list_next(features)) {
- if (G_UNLIKELY(features->data == NULL))
+ if (G_UNLIKELY(features->data == nullptr))
continue;
GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
@@ -866,7 +866,7 @@ QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFac
if (value) {
gchar *str = gst_value_serialize(value);
QString versions = QLatin1String(str);
- const QStringList elements = versions.split(QRegularExpression(QLatin1String("\\D+")), QString::SkipEmptyParts);
+ const QStringList elements = versions.split(QRegularExpression(QLatin1String("\\D+")), Qt::SkipEmptyParts);
for (const QString &e : elements)
supportedMimeTypes.insert(nameLowcase + e);
g_free(str);
@@ -1238,7 +1238,7 @@ GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &format
gst_caps_append_structure(caps, gst_structure_new(
"video/x-raw",
"format" , G_TYPE_STRING, gst_video_format_to_string(qt_videoFormatLookup[index].gstFormat),
- NULL));
+ nullptr));
}
}
#else
@@ -1249,7 +1249,7 @@ GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &format
gst_caps_append_structure(caps, gst_structure_new(
"video/x-raw-yuv",
"format", GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
- NULL));
+ nullptr));
continue;
}
@@ -1265,11 +1265,11 @@ GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &format
"red_mask" , G_TYPE_INT, qt_rgbColorLookup[i].red,
"green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
"blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
- NULL);
+ nullptr);
if (qt_rgbColorLookup[i].alpha != 0) {
gst_structure_set(
- structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL);
+ structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, nullptr);
}
gst_caps_append_structure(caps, structure);
}
@@ -1282,7 +1282,7 @@ GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &format
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
"width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
"height" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- NULL);
+ nullptr);
return caps;
}
@@ -1317,7 +1317,7 @@ void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant
GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(),
tagValue.toString().toUtf8().constData(),
- NULL);
+ nullptr);
break;
case QVariant::Int:
case QVariant::LongLong:
@@ -1325,14 +1325,14 @@ void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant
GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(),
tagValue.toInt(),
- NULL);
+ nullptr);
break;
case QVariant::Double:
gst_tag_setter_add_tags(GST_TAG_SETTER(element),
GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(),
tagValue.toDouble(),
- NULL);
+ nullptr);
break;
#if GST_CHECK_VERSION(0, 10, 31)
case QVariant::DateTime: {
@@ -1343,7 +1343,7 @@ void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant
gst_date_time_new_local_time(
date.date().year(), date.date().month(), date.date().day(),
date.time().hour(), date.time().minute(), date.time().second()),
- NULL);
+ nullptr);
break;
}
#endif
@@ -1604,7 +1604,7 @@ GstCaps *qt_gst_pad_get_current_caps(GstPad *pad)
GstCaps *qt_gst_pad_get_caps(GstPad *pad)
{
#if GST_CHECK_VERSION(1,0,0)
- return gst_pad_query_caps(pad, NULL);
+ return gst_pad_query_caps(pad, nullptr);
#elif GST_CHECK_VERSION(0, 10, 26)
return gst_pad_get_caps_reffed(pad);
#else
@@ -1617,7 +1617,7 @@ GstStructure *qt_gst_structure_new_empty(const char *name)
#if GST_CHECK_VERSION(1,0,0)
return gst_structure_new_empty(name);
#else
- return gst_structure_new(name, NULL);
+ return gst_structure_new(name, nullptr);
#endif
}
@@ -1709,7 +1709,7 @@ static gint qt_gst_compare_ranks(GstPluginFeature *f1, GstPluginFeature *f2)
GList *qt_gst_video_sinks()
{
- GList *list = NULL;
+ GList *list = nullptr;
#if GST_CHECK_VERSION(0, 10, 31)
list = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
@@ -1717,7 +1717,7 @@ GList *qt_gst_video_sinks()
#else
list = gst_registry_feature_filter(gst_registry_get_default(),
(GstPluginFeatureFilter)qt_gst_videosink_factory_filter,
- FALSE, NULL);
+ FALSE, nullptr);
list = g_list_sort(list, (GCompareFunc)qt_gst_compare_ranks);
#endif
diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp
index 3b458a978..9eb2531a1 100644
--- a/src/gsttools/qgstvideorenderersink.cpp
+++ b/src/gsttools/qgstvideorenderersink.cpp
@@ -170,8 +170,8 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surfac
{
const auto instances = rendererLoader()->instances(QGstVideoRendererPluginKey);
for (QObject *instance : instances) {
- QGstVideoRendererInterface* plugin = qobject_cast<QGstVideoRendererInterface*>(instance);
- if (QGstVideoRenderer *renderer = plugin ? plugin->createRenderer() : 0)
+ auto plugin = qobject_cast<QGstVideoRendererInterface*>(instance);
+ if (QGstVideoRenderer *renderer = plugin ? plugin->createRenderer() : nullptr)
m_renderers.append(renderer);
}
@@ -304,7 +304,7 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
#if QT_CONFIG(gstreamer_gl)
static GstGLContext *gstGLDisplayContext(QAbstractVideoSurface *surface)
{
- QOpenGLContext *glContext = qobject_cast<QOpenGLContext*>(surface->property("GLContext").value<QObject*>());
+ auto glContext = qobject_cast<QOpenGLContext*>(surface->property("GLContext").value<QObject*>());
// Context is not ready yet.
if (!glContext)
return nullptr;
@@ -360,7 +360,7 @@ static GstGLContext *gstGLDisplayContext(QAbstractVideoSurface *surface)
qWarning() << "Could not create wrappped context for platform:" << glPlatform;
GstGLContext *displayContext = nullptr;
- GError *error = NULL;
+ GError *error = nullptr;
gst_gl_display_create_context(display, appContext, &displayContext, &error);
if (error) {
qWarning() << "Could not create display context:" << error->message;
@@ -393,14 +393,14 @@ bool QVideoSurfaceGstDelegate::query(GstQuery *query)
if (!m_gstGLDisplayContext)
return false;
- GstContext *context = NULL;
+ GstContext *context = nullptr;
gst_query_parse_context(query, &context);
context = context ? gst_context_copy(context) : gst_context_new(type, FALSE);
GstStructure *structure = gst_context_writable_structure(context);
#if GST_CHECK_VERSION(1,11,1)
- gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, m_gstGLDisplayContext, NULL);
+ gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, m_gstGLDisplayContext, nullptr);
#else
- gst_structure_set(structure, "context", GST_GL_TYPE_CONTEXT, m_gstGLDisplayContext, NULL);
+ gst_structure_set(structure, "context", GST_GL_TYPE_CONTEXT, m_gstGLDisplayContext, nullptr);
#endif
gst_query_set_context(query, context);
gst_context_unref(context);
@@ -583,10 +583,10 @@ GType QGstVideoRendererSink::get_type()
{
sizeof(QGstVideoRendererSinkClass), // class_size
base_init, // base_init
- NULL, // base_finalize
+ nullptr, // base_finalize
class_init, // class_init
- NULL, // class_finalize
- NULL, // class_data
+ nullptr, // class_finalize
+ nullptr, // class_data
sizeof(QGstVideoRendererSink), // instance_size
0, // n_preallocs
instance_init, // instance_init
@@ -694,12 +694,12 @@ void QGstVideoRendererSink::handleShowPrerollChange(GObject *o, GParamSpec *p, g
QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(d);
gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, NULL);
+ g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
if (!showPrerollFrame) {
GstState state = GST_STATE_VOID_PENDING;
GstClockTime timeout = 10000000; // 10 ms
- gst_element_get_state(GST_ELEMENT(sink), &state, NULL, timeout);
+ gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, timeout);
// show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
// the QMediaPlayer was stopped from the paused state.
// We need to flush the current frame.
@@ -714,7 +714,7 @@ GstStateChangeReturn QGstVideoRendererSink::change_state(
QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(element);
gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, NULL);
+ g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);
// If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
// GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index c63eea9a6..c6951bdef 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -69,7 +69,7 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
if (m_surface) {
const auto instances = bufferPoolLoader()->instances(QGstBufferPoolPluginKey);
for (QObject *instance : instances) {
- QGstBufferPoolInterface* plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
+ auto plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
if (plugin) {
m_pools.append(plugin);
@@ -356,10 +356,10 @@ GType QVideoSurfaceGstSink::get_type()
{
sizeof(QVideoSurfaceGstSinkClass), // class_size
base_init, // base_init
- NULL, // base_finalize
+ nullptr, // base_finalize
class_init, // class_init
- NULL, // class_finalize
- NULL, // class_data
+ nullptr, // class_finalize
+ nullptr, // class_data
sizeof(QVideoSurfaceGstSink), // instance_size
0, // n_preallocs
instance_init, // instance_init
@@ -460,11 +460,11 @@ void QVideoSurfaceGstSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gp
QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(d);
gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, NULL);
+ g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
if (!showPrerollFrame) {
GstState state = GST_STATE_VOID_PENDING;
- gst_element_get_state(GST_ELEMENT(sink), &state, NULL, GST_CLOCK_TIME_NONE);
+ gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, GST_CLOCK_TIME_NONE);
// show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
// the QMediaPlayer was stopped from the paused state.
// We need to flush the current frame.
@@ -478,7 +478,7 @@ GstStateChangeReturn QVideoSurfaceGstSink::change_state(GstElement *element, Gst
QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(element);
gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, NULL);
+ g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);
// If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
// GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
@@ -576,7 +576,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
if (!buffer)
return GST_FLOW_ERROR;
- *buffer = NULL;
+ *buffer = nullptr;
if (!sink->delegate->pool())
return GST_FLOW_OK;
@@ -694,7 +694,7 @@ GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer
{
VO_SINK(base);
gboolean showPrerollFrame = true;
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, NULL);
+ g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
if (showPrerollFrame)
return sink->delegate->render(buffer);
diff --git a/src/imports/multimedia/Video.qml b/src/imports/multimedia/Video.qml
index 19c437869..24fde22e1 100644
--- a/src/imports/multimedia/Video.qml
+++ b/src/imports/multimedia/Video.qml
@@ -38,7 +38,7 @@
****************************************************************************/
import QtQuick 2.0
-import QtMultimedia 5.11
+import QtMultimedia 5.13
/*!
\qmltype Video
@@ -125,6 +125,23 @@ Item {
property alias fillMode: videoOut.fillMode
/*!
+ \qmlproperty enumeration Video::flushMode
+
+ Set this property to define what \c Video should show
+ when playback is finished or stopped.
+
+ \list
+ \li VideoOutput.EmptyFrame - clears video output.
+ \li VideoOutput.FirstFrame - shows the first valid frame.
+ \li VideoOutput.LastFrame - shows the last valid frame.
+ \endlist
+
+ The default flush mode is EmptyFrame.
+ \since 5.15
+ */
+ property alias flushMode: videoOut.flushMode
+
+ /*!
\qmlproperty int Video::orientation
The orientation of the \c Video in degrees. Only multiples of 90
diff --git a/src/imports/multimedia/multimedia.cpp b/src/imports/multimedia/multimedia.cpp
index 8aed83d33..0bbe9cae3 100644
--- a/src/imports/multimedia/multimedia.cpp
+++ b/src/imports/multimedia/multimedia.cpp
@@ -60,6 +60,7 @@
#include "qdeclarativecameraimageprocessing_p.h"
#include "qdeclarativecameraviewfinder_p.h"
#include "qdeclarativetorch_p.h"
+#include <QAbstractVideoSurface>
QML_DECLARE_TYPE(QSoundEffect)
@@ -160,6 +161,11 @@ public:
// 5.13 types
qmlRegisterType<QDeclarativeVideoOutput, 13>(uri, 5, 13, "VideoOutput");
+ // 5.15 types
+ qmlRegisterType<QDeclarativeAudio, 15>(uri, 5, 15, "MediaPlayer");
+ qmlRegisterType<QDeclarativeVideoOutput, 15>(uri, 5, 15, "VideoOutput");
+ qmlRegisterType<QAbstractVideoSurface>();
+
// Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
qmlRegisterModule(uri, 5, QT_VERSION_MINOR);
}
diff --git a/src/imports/multimedia/plugins.qmltypes b/src/imports/multimedia/plugins.qmltypes
index 870544160..06fb8918b 100644
--- a/src/imports/multimedia/plugins.qmltypes
+++ b/src/imports/multimedia/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtMultimedia 5.14'
+// 'qmlplugindump -nonrelocatable QtMultimedia 5.15'
Module {
dependencies: ["QtQuick 2.0"]
@@ -288,6 +288,24 @@ Module {
Property { name: "active"; type: "bool" }
}
Component {
+ name: "QAbstractVideoSurface"
+ prototype: "QObject"
+ Property { name: "nativeResolution"; type: "QSize"; isReadonly: true }
+ Signal {
+ name: "activeChanged"
+ Parameter { name: "active"; type: "bool" }
+ }
+ Signal {
+ name: "surfaceFormatChanged"
+ Parameter { name: "format"; type: "QVideoSurfaceFormat" }
+ }
+ Signal { name: "supportedFormatsChanged" }
+ Signal {
+ name: "nativeResolutionChanged"
+ Parameter { name: "resolution"; type: "QSize" }
+ }
+ }
+ Component {
name: "QCamera"
prototype: "QMediaObject"
Enum {
@@ -427,10 +445,11 @@ Module {
"QtMultimedia/Audio 5.9",
"QtMultimedia/MediaPlayer 5.0",
"QtMultimedia/MediaPlayer 5.11",
+ "QtMultimedia/MediaPlayer 5.15",
"QtMultimedia/MediaPlayer 5.6",
"QtMultimedia/MediaPlayer 5.9"
]
- exportMetaObjectRevisions: [0, 3, 1, 2, 0, 3, 1, 2]
+ exportMetaObjectRevisions: [0, 3, 1, 2, 0, 3, 15, 1, 2]
Enum {
name: "Status"
values: {
@@ -524,6 +543,7 @@ Module {
Property { name: "audioRole"; revision: 1; type: "AudioRole" }
Property { name: "customAudioRole"; revision: 3; type: "string" }
Property { name: "notifyInterval"; revision: 2; type: "int" }
+ Property { name: "videoOutput"; revision: 15; type: "QVariant" }
Signal { name: "playlistChanged"; revision: 1 }
Signal { name: "loopCountChanged" }
Signal { name: "paused" }
@@ -541,6 +561,7 @@ Module {
Parameter { name: "errorString"; type: "string" }
}
Signal { name: "notifyIntervalChanged"; revision: 2 }
+ Signal { name: "videoOutputChanged"; revision: 15 }
Method { name: "play" }
Method { name: "pause" }
Method { name: "stop" }
@@ -2025,9 +2046,10 @@ Module {
exports: [
"QtMultimedia/VideoOutput 5.0",
"QtMultimedia/VideoOutput 5.13",
+ "QtMultimedia/VideoOutput 5.15",
"QtMultimedia/VideoOutput 5.2"
]
- exportMetaObjectRevisions: [0, 13, 2]
+ exportMetaObjectRevisions: [0, 13, 15, 2]
Enum {
name: "FlushMode"
values: {
@@ -2052,6 +2074,13 @@ Module {
Property { name: "contentRect"; type: "QRectF"; isReadonly: true }
Property { name: "filters"; type: "QAbstractVideoFilter"; isList: true; isReadonly: true }
Property { name: "flushMode"; revision: 13; type: "FlushMode" }
+ Property {
+ name: "videoSurface"
+ revision: 15
+ type: "QAbstractVideoSurface"
+ isReadonly: true
+ isPointer: true
+ }
Signal {
name: "fillModeChanged"
Parameter { type: "QDeclarativeVideoOutput::FillMode" }
@@ -2124,6 +2153,7 @@ Module {
Parameter { name: "availability"; type: "QMultimedia::AvailabilityStatus" }
}
}
+ Component { name: "QSGVideoItemSurface"; prototype: "QAbstractVideoSurface" }
Component {
name: "QSoundEffect"
prototype: "QObject"
diff --git a/src/imports/multimedia/qdeclarativeaudio.cpp b/src/imports/multimedia/qdeclarativeaudio.cpp
index 9d41c77fa..fcba6257d 100644
--- a/src/imports/multimedia/qdeclarativeaudio.cpp
+++ b/src/imports/multimedia/qdeclarativeaudio.cpp
@@ -45,12 +45,14 @@
#include <qmediaservice.h>
#include <private/qmediaserviceprovider_p.h>
+#include <private/qdeclarativevideooutput_p.h>
#include <qmetadatareadercontrol.h>
#include <qmediaavailabilitycontrol.h>
#include "qdeclarativeplaylist_p.h"
#include "qdeclarativemediametadata_p.h"
+#include <QAbstractVideoSurface>
#include <QTimerEvent>
#include <QtQml/qqmlengine.h>
@@ -130,6 +132,63 @@ QDeclarativeAudio::~QDeclarativeAudio()
}
/*!
+ \since 5.15
+ \qmlproperty url QtMultimedia::MediaPlayer::videoOutput
+
+ This property holds the target video output.
+ Accepts one or an array of QAbstractVideoSurface or VideoOutput elements.
+
+ \snippet multimedia-snippets/multiple-videooutputs.qml complete
+
+ \sa QMediaPlayer::setVideoOutput()
+*/
+
+QVariant QDeclarativeAudio::videoOutput() const
+{
+ return m_videoOutput;
+}
+
+void QDeclarativeAudio::setVideoOutput(const QVariant &v)
+{
+ if (m_videoOutput == v)
+ return;
+
+ QAbstractVideoSurface *surface = nullptr;
+ auto vo = v.value<QDeclarativeVideoOutput *>();
+ if (vo)
+ surface = vo->videoSurface();
+ else
+ surface = v.value<QAbstractVideoSurface *>();
+
+ // If only one object has been passed.
+ if (surface) {
+ m_player->setVideoOutput(surface);
+ } else {
+ QVector<QAbstractVideoSurface *> surfaces;
+ // Check if it is an array.
+ auto arr = v.value<QJSValue>();
+ if (!arr.isNull()) {
+ const int len = arr.property("length").toInt();
+ for (int i = 0; i < len; ++i) {
+ auto &&v = arr.property(i);
+ if (v.isQObject()) {
+ auto obj = v.toQObject();
+ vo = qobject_cast<QDeclarativeVideoOutput *>(obj);
+ surface = vo ? vo->videoSurface() : qobject_cast<QAbstractVideoSurface *>(obj);
+ if (surface)
+ surfaces.append(surface);
+ }
+ }
+ }
+
+ m_player->setVideoOutput(surfaces);
+ }
+
+ m_videoOutput = v;
+ emit videoOutputChanged();
+}
+
+/*!
\qmlproperty enumeration QtMultimedia::Audio::availability
Returns the availability state of the media player.
diff --git a/src/imports/multimedia/qdeclarativeaudio_p.h b/src/imports/multimedia/qdeclarativeaudio_p.h
index 043b36042..dc8800695 100644
--- a/src/imports/multimedia/qdeclarativeaudio_p.h
+++ b/src/imports/multimedia/qdeclarativeaudio_p.h
@@ -97,6 +97,7 @@ class QDeclarativeAudio : public QObject, public QQmlParserStatus
Q_PROPERTY(AudioRole audioRole READ audioRole WRITE setAudioRole NOTIFY audioRoleChanged REVISION 1)
Q_PROPERTY(QString customAudioRole READ customAudioRole WRITE setCustomAudioRole NOTIFY customAudioRoleChanged REVISION 3)
Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged REVISION 2)
+ Q_PROPERTY(QVariant videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged REVISION 15)
Q_ENUMS(Status)
Q_ENUMS(Error)
Q_ENUMS(Loop)
@@ -164,6 +165,9 @@ public:
QDeclarativeAudio(QObject *parent = 0);
~QDeclarativeAudio();
+ QVariant videoOutput() const;
+ void setVideoOutput(const QVariant &);
+
bool hasAudio() const;
bool hasVideo() const;
@@ -269,6 +273,7 @@ Q_SIGNALS:
void mediaObjectChanged();
Q_REVISION(2) void notifyIntervalChanged();
+ Q_REVISION(15) void videoOutputChanged();
private Q_SLOTS:
void _q_error(QMediaPlayer::Error);
@@ -305,6 +310,7 @@ private:
QMediaPlayer *m_player;
int m_notifyInterval;
+ QVariant m_videoOutput;
friend class QDeclarativeMediaBaseAnimation;
};
diff --git a/src/imports/multimedia/qdeclarativecamera.cpp b/src/imports/multimedia/qdeclarativecamera.cpp
index 7730c9900..3a9bc8fa2 100644
--- a/src/imports/multimedia/qdeclarativecamera.cpp
+++ b/src/imports/multimedia/qdeclarativecamera.cpp
@@ -59,9 +59,10 @@
QT_BEGIN_NAMESPACE
-void QDeclarativeCamera::_q_error(QCamera::Error errorCode)
+void QDeclarativeCamera::_q_errorOccurred(QCamera::Error errorCode)
{
emit error(Error(errorCode), errorString());
+ emit errorOccurred(Error(errorCode), errorString());
emit errorChanged();
}
@@ -197,7 +198,7 @@ QDeclarativeCamera::QDeclarativeCamera(QObject *parent) :
this, SIGNAL(lockStatusChanged()));
connect(m_camera, &QCamera::stateChanged, this, &QDeclarativeCamera::_q_updateState);
connect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(cameraStatusChanged()));
- connect(m_camera, SIGNAL(error(QCamera::Error)), this, SLOT(_q_error(QCamera::Error)));
+ connect(m_camera, SIGNAL(errorOccurred(QCamera::Error)), this, SLOT(_q_errorOccurred(QCamera::Error)));
connect(m_camera, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)),
this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus)));
@@ -420,7 +421,7 @@ QDeclarativeCamera::Error QDeclarativeCamera::errorCode() const
This property holds the last error string, if any.
- \sa error, errorCode
+ \sa errorOccurred, errorCode
*/
QString QDeclarativeCamera::errorString() const
{
@@ -752,11 +753,19 @@ void QDeclarativeCamera::setDigitalZoom(qreal value)
\value Camera.NotSupportedFeatureError
The feature is not supported.
- \sa error, errorString
+ \sa errorOccurred, errorString
*/
/*!
\qmlsignal QtMultimedia::Camera::error(errorCode, errorString)
+ \obsolete
+
+ Use errorOccurred() instead.
+*/
+
+/*!
+ \qmlsignal QtMultimedia::Camera::errorOccurred(errorCode, errorString)
+ \since 5.15
This signal is emitted when an error specified by \a errorCode occurs.
A descriptive string value is available in \a errorString.
diff --git a/src/imports/multimedia/qdeclarativecamera_p.h b/src/imports/multimedia/qdeclarativecamera_p.h
index 97afa5b53..41203ac80 100644
--- a/src/imports/multimedia/qdeclarativecamera_p.h
+++ b/src/imports/multimedia/qdeclarativecamera_p.h
@@ -308,7 +308,10 @@ public Q_SLOTS:
Q_SIGNALS:
void errorChanged();
+#if QT_DEPRECATED_SINCE(5,15)
void error(QDeclarativeCamera::Error errorCode, const QString &errorString);
+#endif
+ Q_REVISION(15) void errorOccurred(QDeclarativeCamera::Error errorCode, const QString &errorString);
Q_REVISION(1) void deviceIdChanged();
Q_REVISION(1) void positionChanged();
@@ -332,7 +335,7 @@ Q_SIGNALS:
private Q_SLOTS:
void _q_updateState(QCamera::State);
- void _q_error(QCamera::Error);
+ void _q_errorOccurred(QCamera::Error);
void _q_availabilityChanged(QMultimedia::AvailabilityStatus);
protected:
diff --git a/src/multimedia/audio/qsamplecache_p.cpp b/src/multimedia/audio/qsamplecache_p.cpp
index 8c4fdc210..b293946cc 100644
--- a/src/multimedia/audio/qsamplecache_p.cpp
+++ b/src/multimedia/audio/qsamplecache_p.cpp
@@ -397,7 +397,7 @@ void QSample::load()
qDebug() << "QSample: load [" << m_url << "]";
#endif
m_stream = m_parent->networkAccessManager().get(QNetworkRequest(m_url));
- connect(m_stream, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(decoderError()));
+ connect(m_stream, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), SLOT(decoderError()));
m_waveDecoder = new QWaveDecoder(m_stream);
connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady()));
connect(m_waveDecoder, SIGNAL(parsingError()), SLOT(decoderError()));
diff --git a/src/multimedia/camera/qcamera.cpp b/src/multimedia/camera/qcamera.cpp
index 40441f332..79412b961 100644
--- a/src/multimedia/camera/qcamera.cpp
+++ b/src/multimedia/camera/qcamera.cpp
@@ -109,6 +109,7 @@ void QCameraPrivate::_q_error(int error, const QString &errorString)
this->error = QCamera::Error(error);
this->errorString = errorString;
+ emit q->errorOccurred(this->error);
emit q->error(this->error);
}
@@ -823,7 +824,7 @@ void QCamera::setCaptureMode(QCamera::CaptureModes mode)
Starts the camera.
State is changed to QCamera::ActiveState if camera is started
- successfully, otherwise error() signal is emitted.
+ successfully, otherwise errorOccurred() signal is emitted.
While the camera state is changed to QCamera::ActiveState,
starting the camera service can be asynchronous with the actual
@@ -1271,6 +1272,14 @@ void QCamera::unlock()
/*!
\fn void QCamera::error(QCamera::Error value)
+ \obsolete
+
+ Use errorOccurred() instead.
+*/
+
+/*!
+ \fn void QCamera::errorOccurred(QCamera::Error value)
+ \since 5.15
Signal emitted when error state changes to \a value.
*/
diff --git a/src/multimedia/camera/qcamera.h b/src/multimedia/camera/qcamera.h
index b2582cd19..97cf4509b 100644
--- a/src/multimedia/camera/qcamera.h
+++ b/src/multimedia/camera/qcamera.h
@@ -242,7 +242,10 @@ Q_SIGNALS:
void lockStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason);
void lockStatusChanged(QCamera::LockType lock, QCamera::LockStatus status, QCamera::LockChangeReason reason);
+#if QT_DEPRECATED_SINCE(5,15)
void error(QCamera::Error);
+#endif
+ void errorOccurred(QCamera::Error);
private:
Q_DISABLE_COPY(QCamera)
diff --git a/src/multimedia/controls/qaudiodecodercontrol.cpp b/src/multimedia/controls/qaudiodecodercontrol.cpp
index 4d6d36a2f..711303174 100644
--- a/src/multimedia/controls/qaudiodecodercontrol.cpp
+++ b/src/multimedia/controls/qaudiodecodercontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QAudioDecoderControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qaudioencodersettingscontrol.cpp b/src/multimedia/controls/qaudioencodersettingscontrol.cpp
index 42f20201c..5ae473178 100644
--- a/src/multimedia/controls/qaudioencodersettingscontrol.cpp
+++ b/src/multimedia/controls/qaudioencodersettingscontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QAudioEncoderSettingsControl
+ \obsolete
\inmodule QtMultimedia
\ingroup multimedia_control
diff --git a/src/multimedia/controls/qaudioinputselectorcontrol.cpp b/src/multimedia/controls/qaudioinputselectorcontrol.cpp
index 0f8843808..649891225 100644
--- a/src/multimedia/controls/qaudioinputselectorcontrol.cpp
+++ b/src/multimedia/controls/qaudioinputselectorcontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QAudioInputSelectorControl
+ \obsolete
\brief The QAudioInputSelectorControl class provides an audio input selector media control.
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qaudiooutputselectorcontrol.cpp b/src/multimedia/controls/qaudiooutputselectorcontrol.cpp
index 20c792f8d..64886e4c9 100644
--- a/src/multimedia/controls/qaudiooutputselectorcontrol.cpp
+++ b/src/multimedia/controls/qaudiooutputselectorcontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QAudioOutputSelectorControl
+ \obsolete
\brief The QAudioOutputSelectorControl class provides an audio output selector media control.
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qaudiorolecontrol.cpp b/src/multimedia/controls/qaudiorolecontrol.cpp
index 7b2341846..01e60a914 100644
--- a/src/multimedia/controls/qaudiorolecontrol.cpp
+++ b/src/multimedia/controls/qaudiorolecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QAudioRoleControl
+ \obsolete
\inmodule QtMultimedia
\ingroup multimedia_control
\since 5.6
diff --git a/src/multimedia/controls/qcameracapturebufferformatcontrol.cpp b/src/multimedia/controls/qcameracapturebufferformatcontrol.cpp
index 553414681..8f0c3e6e9 100644
--- a/src/multimedia/controls/qcameracapturebufferformatcontrol.cpp
+++ b/src/multimedia/controls/qcameracapturebufferformatcontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraCaptureBufferFormatControl
+ \obsolete
\brief The QCameraCaptureBufferFormatControl class provides a control for setting the capture buffer format.
diff --git a/src/multimedia/controls/qcameracapturedestinationcontrol.cpp b/src/multimedia/controls/qcameracapturedestinationcontrol.cpp
index e037ab5a9..a9a54a3b8 100644
--- a/src/multimedia/controls/qcameracapturedestinationcontrol.cpp
+++ b/src/multimedia/controls/qcameracapturedestinationcontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraCaptureDestinationControl
+ \obsolete
\brief The QCameraCaptureDestinationControl class provides a control for setting capture destination.
diff --git a/src/multimedia/controls/qcameracontrol.cpp b/src/multimedia/controls/qcameracontrol.cpp
index 03a7a073c..d33fa94c9 100644
--- a/src/multimedia/controls/qcameracontrol.cpp
+++ b/src/multimedia/controls/qcameracontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraControl
+ \obsolete
diff --git a/src/multimedia/controls/qcameraexposurecontrol.cpp b/src/multimedia/controls/qcameraexposurecontrol.cpp
index 1434f0976..2095c9cfa 100644
--- a/src/multimedia/controls/qcameraexposurecontrol.cpp
+++ b/src/multimedia/controls/qcameraexposurecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraExposureControl
+ \obsolete
\brief The QCameraExposureControl class allows controlling camera exposure parameters.
diff --git a/src/multimedia/controls/qcamerafeedbackcontrol.cpp b/src/multimedia/controls/qcamerafeedbackcontrol.cpp
index 07074d83d..42cd7d661 100644
--- a/src/multimedia/controls/qcamerafeedbackcontrol.cpp
+++ b/src/multimedia/controls/qcamerafeedbackcontrol.cpp
@@ -44,6 +44,7 @@
/*!
\class QCameraFeedbackControl
+ \obsolete
\brief The QCameraFeedbackControl class allows controlling feedback (sounds etc) during camera operation.
diff --git a/src/multimedia/controls/qcameraflashcontrol.cpp b/src/multimedia/controls/qcameraflashcontrol.cpp
index d5d9b564f..658e2d56c 100644
--- a/src/multimedia/controls/qcameraflashcontrol.cpp
+++ b/src/multimedia/controls/qcameraflashcontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraFlashControl
+ \obsolete
\brief The QCameraFlashControl class allows controlling a camera's flash.
diff --git a/src/multimedia/controls/qcamerafocuscontrol.cpp b/src/multimedia/controls/qcamerafocuscontrol.cpp
index d963c95d4..b216882b4 100644
--- a/src/multimedia/controls/qcamerafocuscontrol.cpp
+++ b/src/multimedia/controls/qcamerafocuscontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraFocusControl
+ \obsolete
\brief The QCameraFocusControl class supplies control for
diff --git a/src/multimedia/controls/qcameraimagecapturecontrol.cpp b/src/multimedia/controls/qcameraimagecapturecontrol.cpp
index 3c110eb68..0e089d01b 100644
--- a/src/multimedia/controls/qcameraimagecapturecontrol.cpp
+++ b/src/multimedia/controls/qcameraimagecapturecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraImageCaptureControl
+ \obsolete
\brief The QCameraImageCaptureControl class provides a control interface
for image capture services.
diff --git a/src/multimedia/controls/qcameraimageprocessingcontrol.cpp b/src/multimedia/controls/qcameraimageprocessingcontrol.cpp
index a39846642..fba4bf400 100644
--- a/src/multimedia/controls/qcameraimageprocessingcontrol.cpp
+++ b/src/multimedia/controls/qcameraimageprocessingcontrol.cpp
@@ -51,6 +51,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageProcessingControlMetaTypes)
/*!
\class QCameraImageProcessingControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qcamerainfocontrol.cpp b/src/multimedia/controls/qcamerainfocontrol.cpp
index de6dc4277..8a4ef3b44 100644
--- a/src/multimedia/controls/qcamerainfocontrol.cpp
+++ b/src/multimedia/controls/qcamerainfocontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraInfoControl
+ \obsolete
\since 5.3
\brief The QCameraInfoControl class provides a camera info media control.
diff --git a/src/multimedia/controls/qcameralockscontrol.cpp b/src/multimedia/controls/qcameralockscontrol.cpp
index 436b3b9c9..27b68cf2c 100644
--- a/src/multimedia/controls/qcameralockscontrol.cpp
+++ b/src/multimedia/controls/qcameralockscontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraLocksControl
+ \obsolete
diff --git a/src/multimedia/controls/qcameraviewfindersettingscontrol.cpp b/src/multimedia/controls/qcameraviewfindersettingscontrol.cpp
index 6fa0ded82..bd5c7a73b 100644
--- a/src/multimedia/controls/qcameraviewfindersettingscontrol.cpp
+++ b/src/multimedia/controls/qcameraviewfindersettingscontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraViewfinderSettingsControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qcamerazoomcontrol.cpp b/src/multimedia/controls/qcamerazoomcontrol.cpp
index 9c8d8d289..1f0835224 100644
--- a/src/multimedia/controls/qcamerazoomcontrol.cpp
+++ b/src/multimedia/controls/qcamerazoomcontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCameraZoomControl
+ \obsolete
\brief The QCameraZoomControl class supplies control for
diff --git a/src/multimedia/controls/qcustomaudiorolecontrol.cpp b/src/multimedia/controls/qcustomaudiorolecontrol.cpp
index 046219687..f1b89eda5 100644
--- a/src/multimedia/controls/qcustomaudiorolecontrol.cpp
+++ b/src/multimedia/controls/qcustomaudiorolecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QCustomAudioRoleControl
+ \obsolete
\inmodule QtMultimedia
\ingroup multimedia_control
\since 5.11
diff --git a/src/multimedia/controls/qimageencodercontrol.cpp b/src/multimedia/controls/qimageencodercontrol.cpp
index c29a61662..6223c33c7 100644
--- a/src/multimedia/controls/qimageencodercontrol.cpp
+++ b/src/multimedia/controls/qimageencodercontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QImageEncoderControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmediaaudioprobecontrol.cpp b/src/multimedia/controls/qmediaaudioprobecontrol.cpp
index 296f01888..e22135903 100644
--- a/src/multimedia/controls/qmediaaudioprobecontrol.cpp
+++ b/src/multimedia/controls/qmediaaudioprobecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaAudioProbeControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmediaavailabilitycontrol.cpp b/src/multimedia/controls/qmediaavailabilitycontrol.cpp
index 1a6d73a8a..68b404369 100644
--- a/src/multimedia/controls/qmediaavailabilitycontrol.cpp
+++ b/src/multimedia/controls/qmediaavailabilitycontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaAvailabilityControl
+ \obsolete
\brief The QMediaAvailabilityControl class supplies a control for reporting availability of a service.
diff --git a/src/multimedia/controls/qmediacontainercontrol.cpp b/src/multimedia/controls/qmediacontainercontrol.cpp
index b15c8acdc..2b2c8b78b 100644
--- a/src/multimedia/controls/qmediacontainercontrol.cpp
+++ b/src/multimedia/controls/qmediacontainercontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaContainerControl
+ \obsolete
\brief The QMediaContainerControl class provides access to the output container format of a QMediaService.
diff --git a/src/multimedia/controls/qmediagaplessplaybackcontrol.cpp b/src/multimedia/controls/qmediagaplessplaybackcontrol.cpp
index b76274972..c9f531454 100644
--- a/src/multimedia/controls/qmediagaplessplaybackcontrol.cpp
+++ b/src/multimedia/controls/qmediagaplessplaybackcontrol.cpp
@@ -42,6 +42,7 @@
/*!
\class QMediaGaplessPlaybackControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmedianetworkaccesscontrol.cpp b/src/multimedia/controls/qmedianetworkaccesscontrol.cpp
index 9e9ad239d..9d3f14501 100644
--- a/src/multimedia/controls/qmedianetworkaccesscontrol.cpp
+++ b/src/multimedia/controls/qmedianetworkaccesscontrol.cpp
@@ -43,7 +43,9 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaNetworkAccessControl
+ \obsolete
\brief The QMediaNetworkAccessControl class allows the setting of the Network Access Point for media related activities.
+ \obsolete
\inmodule QtMultimedia
@@ -92,6 +94,7 @@ QMediaNetworkAccessControl::~QMediaNetworkAccessControl()
/*!
\fn QMediaNetworkAccessControl::configurationChanged(const QNetworkConfiguration &configuration)
+
This signal is emitted when the current active network configuration changes
to \a configuration.
*/
diff --git a/src/multimedia/controls/qmedianetworkaccesscontrol.h b/src/multimedia/controls/qmedianetworkaccesscontrol.h
index daae4f389..0c14961cf 100644
--- a/src/multimedia/controls/qmedianetworkaccesscontrol.h
+++ b/src/multimedia/controls/qmedianetworkaccesscontrol.h
@@ -41,6 +41,10 @@
#ifndef QMEDIANETWORKACCESSCONTROL_H
#define QMEDIANETWORKACCESSCONTROL_H
+#if 0
+#pragma qt_class(QMediaNetworkAccessControl)
+#endif
+
#include <QtMultimedia/qmediacontrol.h>
#include <QtCore/qlist.h>
@@ -48,10 +52,12 @@
QT_BEGIN_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
// Required for QDoc workaround
class QString;
-
-class Q_MULTIMEDIA_EXPORT QMediaNetworkAccessControl : public QMediaControl
+class QT_DEPRECATED_VERSION_5_15 Q_MULTIMEDIA_EXPORT QMediaNetworkAccessControl : public QMediaControl
{
Q_OBJECT
public:
@@ -71,6 +77,8 @@ protected:
#define QMediaNetworkAccessControl_iid "org.qt-project.qt.medianetworkaccesscontrol/5.0"
Q_MEDIA_DECLARE_CONTROL(QMediaNetworkAccessControl, QMediaNetworkAccessControl_iid)
+QT_WARNING_POP
+
QT_END_NAMESPACE
diff --git a/src/multimedia/controls/qmediaplayercontrol.cpp b/src/multimedia/controls/qmediaplayercontrol.cpp
index 28b217af8..a180413b9 100644
--- a/src/multimedia/controls/qmediaplayercontrol.cpp
+++ b/src/multimedia/controls/qmediaplayercontrol.cpp
@@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaPlayerControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmediarecordercontrol.cpp b/src/multimedia/controls/qmediarecordercontrol.cpp
index f078073ef..87ace7017 100644
--- a/src/multimedia/controls/qmediarecordercontrol.cpp
+++ b/src/multimedia/controls/qmediarecordercontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaRecorderControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmediastreamscontrol.cpp b/src/multimedia/controls/qmediastreamscontrol.cpp
index aa5fe007d..2db9eb6fc 100644
--- a/src/multimedia/controls/qmediastreamscontrol.cpp
+++ b/src/multimedia/controls/qmediastreamscontrol.cpp
@@ -52,6 +52,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterMediaStreamControlMetaTypes)
/*!
\class QMediaStreamsControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmediavideoprobecontrol.cpp b/src/multimedia/controls/qmediavideoprobecontrol.cpp
index ea27ab057..4a85d56d0 100644
--- a/src/multimedia/controls/qmediavideoprobecontrol.cpp
+++ b/src/multimedia/controls/qmediavideoprobecontrol.cpp
@@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaVideoProbeControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmetadatareadercontrol.cpp b/src/multimedia/controls/qmetadatareadercontrol.cpp
index e728353f6..f01ffec38 100644
--- a/src/multimedia/controls/qmetadatareadercontrol.cpp
+++ b/src/multimedia/controls/qmetadatareadercontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMetaDataReaderControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qmetadatawritercontrol.cpp b/src/multimedia/controls/qmetadatawritercontrol.cpp
index 053597b88..6221edaa1 100644
--- a/src/multimedia/controls/qmetadatawritercontrol.cpp
+++ b/src/multimedia/controls/qmetadatawritercontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMetaDataWriterControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qradiodatacontrol.cpp b/src/multimedia/controls/qradiodatacontrol.cpp
index df0046b5e..27e192674 100644
--- a/src/multimedia/controls/qradiodatacontrol.cpp
+++ b/src/multimedia/controls/qradiodatacontrol.cpp
@@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QRadioDataControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qradiotunercontrol.cpp b/src/multimedia/controls/qradiotunercontrol.cpp
index ea2126319..20897150b 100644
--- a/src/multimedia/controls/qradiotunercontrol.cpp
+++ b/src/multimedia/controls/qradiotunercontrol.cpp
@@ -46,9 +46,9 @@ QT_BEGIN_NAMESPACE
/*!
\class QRadioTunerControl
+ \obsolete
\inmodule QtMultimedia
-
\ingroup multimedia_control
diff --git a/src/multimedia/controls/qvideodeviceselectorcontrol.cpp b/src/multimedia/controls/qvideodeviceselectorcontrol.cpp
index 8c4ee7ba4..420ba9150 100644
--- a/src/multimedia/controls/qvideodeviceselectorcontrol.cpp
+++ b/src/multimedia/controls/qvideodeviceselectorcontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVideoDeviceSelectorControl
+ \obsolete
\brief The QVideoDeviceSelectorControl class provides an video device selector media control.
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qvideoencodersettingscontrol.cpp b/src/multimedia/controls/qvideoencodersettingscontrol.cpp
index 52ae51382..64643f6db 100644
--- a/src/multimedia/controls/qvideoencodersettingscontrol.cpp
+++ b/src/multimedia/controls/qvideoencodersettingscontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVideoEncoderSettingsControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/controls/qvideorenderercontrol.cpp b/src/multimedia/controls/qvideorenderercontrol.cpp
index e722dfa38..eee20d59e 100644
--- a/src/multimedia/controls/qvideorenderercontrol.cpp
+++ b/src/multimedia/controls/qvideorenderercontrol.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVideoRendererControl
+ \obsolete
\inmodule QtMultimedia
\brief The QVideoRendererControl class provides a media control for rendering video to a QAbstractVideoSurface.
diff --git a/src/multimedia/controls/qvideowindowcontrol.cpp b/src/multimedia/controls/qvideowindowcontrol.cpp
index e971a6925..a6b2bf407 100644
--- a/src/multimedia/controls/qvideowindowcontrol.cpp
+++ b/src/multimedia/controls/qvideowindowcontrol.cpp
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVideoWindowControl
+ \obsolete
\inmodule QtMultimedia
diff --git a/src/multimedia/doc/snippets/multimedia-snippets/multimedia-snippets.pro b/src/multimedia/doc/snippets/multimedia-snippets/multimedia-snippets.pro
index c13090a79..a46b20bd0 100644
--- a/src/multimedia/doc/snippets/multimedia-snippets/multimedia-snippets.pro
+++ b/src/multimedia/doc/snippets/multimedia-snippets/multimedia-snippets.pro
@@ -22,4 +22,5 @@ SOURCES += \
OTHER_FILES += \
soundeffect.qml \
- qtvideosink.qml
+ qtvideosink.qml \
+ multiple-videooutputs.qml
diff --git a/src/multimedia/video/qvideoframe_p.h b/src/multimedia/doc/snippets/multimedia-snippets/multiple-videooutputs.qml
index d7b9dd348..e3c1587f6 100644
--- a/src/multimedia/video/qvideoframe_p.h
+++ b/src/multimedia/doc/snippets/multimedia-snippets/multiple-videooutputs.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
@@ -37,27 +37,31 @@
**
****************************************************************************/
-#ifndef QVIDEOFRAME_P_H
-#define QVIDEOFRAME_P_H
+import QtQuick 2.0
+import QtQuick.Window 2.2
+import QtMultimedia 5.15
-#include <QtMultimedia/qvideoframe.h>
+//! [complete]
+Item {
+ MediaPlayer {
+ id: mediaplayer
+ autoPlay: true
+ source: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
+ videoOutput: [v1, v2]
+ }
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-Q_MULTIMEDIA_EXPORT QImage qt_imageFromVideoFrame(const QVideoFrame &frame);
-
-QT_END_NAMESPACE
-
-#endif // QVIDEOFRAME_P_H
+ VideoOutput {
+ id: v1
+ anchors.fill: parent
+ }
+ Window {
+ visible: true
+ width: 480; height: 320
+ VideoOutput {
+ id: v2
+ anchors.fill: parent
+ }
+ }
+}
+//! [complete]
diff --git a/src/multimedia/doc/snippets/multimedia-snippets/video.cpp b/src/multimedia/doc/snippets/multimedia-snippets/video.cpp
index 3c14f7009..46327e3d6 100644
--- a/src/multimedia/doc/snippets/multimedia-snippets/video.cpp
+++ b/src/multimedia/doc/snippets/multimedia-snippets/video.cpp
@@ -117,6 +117,7 @@ public:
void VideoWidget();
void VideoWindowControl();
void VideoWidgetControl();
+ void VideoSurface();
private:
// Common naming
@@ -163,6 +164,28 @@ void VideoExample::VideoWidget()
//! [Setting surface in player]
}
+void VideoExample::VideoSurface()
+{
+ //! [Widget Surface]
+ QImage img = QImage("images/qt-logo.png").convertToFormat(QImage::Format_ARGB32);
+ QVideoSurfaceFormat format(img.size(), QVideoFrame::Format_ARGB32);
+ videoWidget = new QVideoWidget;
+ videoWidget->videoSurface()->start(format);
+ videoWidget->videoSurface()->present(img);
+ videoWidget->show();
+ //! [Widget Surface]
+
+ //! [GraphicsVideoItem Surface]
+ QGraphicsVideoItem *item = new QGraphicsVideoItem;
+ graphicsView->scene()->addItem(item);
+ graphicsView->show();
+ QImage img = QImage("images/qt-logo.png").convertToFormat(QImage::Format_ARGB32);
+ QVideoSurfaceFormat format(img.size(), QVideoFrame::Format_ARGB32);
+ item->videoSurface()->start(format);
+ item->videoSurface()->present(img);
+ //! [GraphicsVideoItem Surface]
+}
+
void VideoExample::VideoWidgetControl()
{
//! [Video widget control]
diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp
index 2c66ad06a..3773cfe64 100644
--- a/src/multimedia/playback/qmediaplayer.cpp
+++ b/src/multimedia/playback/qmediaplayer.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qmediaplayer.h"
+#include "qvideosurfaces_p.h"
#include "qvideosurfaceoutput_p.h"
#include "qmediaobject_p.h"
@@ -563,7 +564,7 @@ static QMediaService *playerService(QMediaPlayer::Flags flags)
{
QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider();
if (flags) {
- QMediaServiceProviderHint::Features features = 0;
+ QMediaServiceProviderHint::Features features;
if (flags & QMediaPlayer::LowLatency)
features |= QMediaServiceProviderHint::LowLatencyPlayback;
@@ -731,6 +732,8 @@ void QMediaPlayer::setPlaylist(QMediaPlaylist *playlist)
}
/*!
+ \obsolete
+
Sets the network access points for remote media playback.
\a configurations contains, in ascending preferential order, a list of
configuration that can be used for network access.
@@ -870,6 +873,8 @@ QString QMediaPlayer::errorString() const
}
/*!
+ \obsolete
+
Returns the current network access point in use.
If a default contructed QNetworkConfiguration is returned
this feature is not available or that none of the
@@ -1005,8 +1010,9 @@ void QMediaPlayer::setPlaybackRate(qreal rate)
Sets the current \a media source.
If a \a stream is supplied; media data will be read from it instead of resolving the media
- source. In this case the media source may still be used to resolve additional information
+ source. In this case the url should be provided to resolve additional information
about the media such as mime type. The \a stream must be open and readable.
+ For macOS the \a stream should be also seekable.
Setting the media to a null QMediaContent will cause the player to discard all
information relating to the current media source and to cease all I/O operations related
@@ -1185,6 +1191,24 @@ void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface)
}
}
+/*!
+ \since 5.15
+ Sets multiple video surfaces as the video output of a media player.
+ This allows the media player to render video frames on different surfaces.
+
+ All video surfaces must support at least one shared \c QVideoFrame::PixelFormat.
+
+ If a video output has already been set on the media player the new surfaces
+ will replace it.
+
+ \sa QAbstractVideoSurface::supportedPixelFormats
+*/
+
+void QMediaPlayer::setVideoOutput(const QVector<QAbstractVideoSurface *> &surfaces)
+{
+ setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr);
+}
+
/*! \reimp */
QMultimedia::AvailabilityStatus QMediaPlayer::availability() const
{
@@ -1559,7 +1583,7 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
This value is a multiplier applied to the media's standard play rate. By
default this value is 1.0, indicating that the media is playing at the
standard pace. Values higher than 1.0 will increase the rate of play.
- Values less than zero can be set and indicate the media will rewind at the
+ Values less than zero can be set and indicate the media should rewind at the
multiplier of the standard pace.
Not all playback services support change of the playback rate. It is
@@ -1644,6 +1668,7 @@ QStringList QMediaPlayer::supportedCustomAudioRoles() const
/*!
\fn void QMediaPlayer::networkConfigurationChanged(const QNetworkConfiguration &configuration)
+ \obsolete
Signal that the active in use network access point has been changed to \a configuration and all subsequent network access will use this \a configuration.
*/
diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h
index 5d9a393e1..bd070328b 100644
--- a/src/multimedia/playback/qmediaplayer.h
+++ b/src/multimedia/playback/qmediaplayer.h
@@ -40,6 +40,7 @@
#ifndef QMEDIAPLAYER_H
#define QMEDIAPLAYER_H
+#include <QtMultimedia/qtmultimediaglobal.h>
#include <QtMultimedia/qmediaobject.h>
#include <QtMultimedia/qmediacontent.h>
#include <QtMultimedia/qmediaenumdebug.h>
@@ -131,6 +132,7 @@ public:
void setVideoOutput(QVideoWidget *);
void setVideoOutput(QGraphicsVideoItem *);
void setVideoOutput(QAbstractVideoSurface *surface);
+ void setVideoOutput(const QVector<QAbstractVideoSurface *> &surfaces);
QMediaContent media() const;
const QIODevice *mediaStream() const;
@@ -156,7 +158,10 @@ public:
Error error() const;
QString errorString() const;
- QNetworkConfiguration currentNetworkConfiguration() const;
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ QT_DEPRECATED_VERSION_5_15 QNetworkConfiguration currentNetworkConfiguration() const;
+QT_WARNING_POP
QMultimedia::AvailabilityStatus availability() const override;
@@ -181,7 +186,14 @@ public Q_SLOTS:
void setMedia(const QMediaContent &media, QIODevice *stream = nullptr);
void setPlaylist(QMediaPlaylist *playlist);
- void setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations);
+#ifndef Q_MOC_RUN // moc fails to parse the expanded macro
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#endif
+ QT_DEPRECATED_VERSION_5_15 void setNetworkConfigurations(const QList<QNetworkConfiguration> &configurations);
+#ifndef Q_MOC_RUN // moc fails to parse the expanded macro
+QT_WARNING_POP
+#endif
Q_SIGNALS:
void mediaChanged(const QMediaContent &media);
@@ -208,7 +220,14 @@ Q_SIGNALS:
void error(QMediaPlayer::Error error);
- void networkConfigurationChanged(const QNetworkConfiguration &configuration);
+#ifndef Q_MOC_RUN // moc fails to parse the expanded macro
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#endif
+ QT_DEPRECATED_VERSION_5_15 void networkConfigurationChanged(const QNetworkConfiguration &configuration);
+#ifndef Q_MOC_RUN // moc fails to parse the expanded macro
+QT_WARNING_POP
+#endif
public:
bool bind(QObject *) override;
void unbind(QObject *) override;
diff --git a/src/multimedia/playback/qplaylistfileparser.cpp b/src/multimedia/playback/qplaylistfileparser.cpp
index 9af447032..d3cd60476 100644
--- a/src/multimedia/playback/qplaylistfileparser.cpp
+++ b/src/multimedia/playback/qplaylistfileparser.cpp
@@ -552,7 +552,7 @@ void QPlaylistFileParser::start(const QNetworkRequest& request, const QString &m
d->m_source.reset(d->m_mgr.get(request));
connect(d->m_source.data(), SIGNAL(readyRead()), this, SLOT(handleData()));
connect(d->m_source.data(), SIGNAL(finished()), this, SLOT(handleData()));
- connect(d->m_source.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleError()));
+ connect(d->m_source.data(), SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(handleError()));
if (url.isLocalFile())
d->handleData();
diff --git a/src/multimedia/qmediacontrol.cpp b/src/multimedia/qmediacontrol.cpp
index b8f980aa0..6f0a980a2 100644
--- a/src/multimedia/qmediacontrol.cpp
+++ b/src/multimedia/qmediacontrol.cpp
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaControl
+ \obsolete
\inmodule QtMultimedia
\ingroup multimedia
diff --git a/src/multimedia/qmediapluginloader.cpp b/src/multimedia/qmediapluginloader.cpp
index 88bd591c2..3e9e6cc21 100644
--- a/src/multimedia/qmediapluginloader.cpp
+++ b/src/multimedia/qmediapluginloader.cpp
@@ -104,7 +104,7 @@ QList<QObject*> QMediaPluginLoader::instances(QString const &key)
static const bool showDebug = qEnvironmentVariableIntValue("QT_DEBUG_PLUGINS");
static const QStringList preferredPlugins =
- qEnvironmentVariable("QT_MULTIMEDIA_PREFERRED_PLUGINS").split(QLatin1Char(','), QString::SkipEmptyParts);
+ qEnvironmentVariable("QT_MULTIMEDIA_PREFERRED_PLUGINS").split(QLatin1Char(','), Qt::SkipEmptyParts);
for (int i = preferredPlugins.size() - 1; i >= 0; --i) {
auto name = preferredPlugins[i];
bool found = false;
diff --git a/src/multimedia/qmediaservice.cpp b/src/multimedia/qmediaservice.cpp
index 7ea24c6dc..ad543acae 100644
--- a/src/multimedia/qmediaservice.cpp
+++ b/src/multimedia/qmediaservice.cpp
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QMediaService
+ \obsolete
\brief The QMediaService class provides a common base class for media
service implementations.
\ingroup multimedia
diff --git a/src/multimedia/qmediaserviceprovider.cpp b/src/multimedia/qmediaserviceprovider.cpp
index d8ffe42ae..93b560d8c 100644
--- a/src/multimedia/qmediaserviceprovider.cpp
+++ b/src/multimedia/qmediaserviceprovider.cpp
@@ -56,7 +56,7 @@ class QMediaServiceProviderHintPrivate : public QSharedData
{
public:
QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
- :type(type), cameraPosition(QCamera::UnspecifiedPosition), features(nullptr)
+ : type(type)
{
}
@@ -77,7 +77,7 @@ public:
QMediaServiceProviderHint::Type type;
QByteArray device;
- QCamera::Position cameraPosition;
+ QCamera::Position cameraPosition = QCamera::UnspecifiedPosition;
QString mimeType;
QStringList codecs;
QMediaServiceProviderHint::Features features;
@@ -712,7 +712,7 @@ QMediaServiceProviderHint::Features QMediaServiceProvider::supportedFeatures(con
{
Q_UNUSED(service);
- return QMediaServiceProviderHint::Features(nullptr);
+ return {};
}
/*!
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp
index 5e2d6df39..fd7b74075 100644
--- a/src/multimedia/video/qvideoframe.cpp
+++ b/src/multimedia/video/qvideoframe.cpp
@@ -39,7 +39,6 @@
#include "qvideoframe.h"
-#include "qvideoframe_p.h"
#include "qimagevideobuffer_p.h"
#include "qmemoryvideobuffer_p.h"
#include "qvideoframeconversionhelper_p.h"
@@ -1112,11 +1111,12 @@ static void qInitConvertFuncsAsm()
}
/*!
- \internal
+ Based on the pixel format converts current video frame to image.
+ \since 5.15
*/
-QImage qt_imageFromVideoFrame(const QVideoFrame &f)
+QImage QVideoFrame::image() const
{
- QVideoFrame &frame = const_cast<QVideoFrame&>(f);
+ QVideoFrame frame = *this;
QImage result;
if (!frame.isValid() || !frame.map(QAbstractVideoBuffer::ReadOnly))
diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h
index 8fcf47fc4..d043442a3 100644
--- a/src/multimedia/video/qvideoframe.h
+++ b/src/multimedia/video/qvideoframe.h
@@ -166,6 +166,8 @@ public:
QVariant metaData(const QString &key) const;
void setMetaData(const QString &key, const QVariant &value);
+ QImage image() const;
+
static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
diff --git a/src/multimedia/video/qvideosurfaces.cpp b/src/multimedia/video/qvideosurfaces.cpp
new file mode 100644
index 000000000..793879382
--- /dev/null
+++ b/src/multimedia/video/qvideosurfaces.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvideosurfaces_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QVideoSurfaces::QVideoSurfaces(const QVector<QAbstractVideoSurface *> &s, QObject *parent)
+ : QAbstractVideoSurface(parent)
+ , m_surfaces(s)
+{
+ for (auto a : s) {
+ connect(a, &QAbstractVideoSurface::supportedFormatsChanged, this, [this, a] {
+ auto context = property("GLContext").value<QObject *>();
+ if (!context)
+ setProperty("GLContext", a->property("GLContext"));
+
+ emit supportedFormatsChanged();
+ });
+ }
+}
+
+QVideoSurfaces::~QVideoSurfaces()
+{
+}
+
+QList<QVideoFrame::PixelFormat> QVideoSurfaces::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
+{
+ QList<QVideoFrame::PixelFormat> result;
+ QMap<QVideoFrame::PixelFormat, int> formats;
+ for (auto &s : m_surfaces) {
+ for (auto &p : s->supportedPixelFormats(type)) {
+ if (++formats[p] == m_surfaces.size())
+ result << p;
+ }
+ }
+
+ return result;
+}
+
+bool QVideoSurfaces::start(const QVideoSurfaceFormat &format)
+{
+ bool result = true;
+ for (auto &s : m_surfaces)
+ result &= s->start(format);
+
+ return result && QAbstractVideoSurface::start(format);
+}
+
+void QVideoSurfaces::stop()
+{
+ for (auto &s : m_surfaces)
+ s->stop();
+
+ QAbstractVideoSurface::stop();
+}
+
+bool QVideoSurfaces::present(const QVideoFrame &frame)
+{
+ bool result = true;
+ for (auto &s : m_surfaces)
+ result &= s->present(frame);
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/video/qvideosurfaces_p.h b/src/multimedia/video/qvideosurfaces_p.h
new file mode 100644
index 000000000..67831e74e
--- /dev/null
+++ b/src/multimedia/video/qvideosurfaces_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVIDEOSURFACES_P_H
+#define QVIDEOSURFACES_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QAbstractVideoSurface>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+class QVideoSurfaces : public QAbstractVideoSurface
+{
+public:
+ QVideoSurfaces(const QVector<QAbstractVideoSurface *> &surfaces, QObject *parent = nullptr);
+ ~QVideoSurfaces();
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override;
+ bool start(const QVideoSurfaceFormat &format) override;
+ void stop() override;
+ bool present(const QVideoFrame &frame) override;
+
+private:
+ QVector<QAbstractVideoSurface *> m_surfaces;
+ Q_DISABLE_COPY(QVideoSurfaces)
+};
+
+QT_END_NAMESPACE
+
+#endif // QVIDEOSURFACES_P_H
diff --git a/src/multimedia/video/video.pri b/src/multimedia/video/video.pri
index e5fa697ce..a3668ba4a 100644
--- a/src/multimedia/video/video.pri
+++ b/src/multimedia/video/video.pri
@@ -15,8 +15,8 @@ PRIVATE_HEADERS += \
video/qmemoryvideobuffer_p.h \
video/qvideooutputorientationhandler_p.h \
video/qvideosurfaceoutput_p.h \
- video/qvideoframe_p.h \
- video/qvideoframeconversionhelper_p.h
+ video/qvideoframeconversionhelper_p.h \
+ video/qvideosurfaces_p.h
SOURCES += \
video/qabstractvideobuffer.cpp \
@@ -29,7 +29,8 @@ SOURCES += \
video/qvideosurfaceoutput.cpp \
video/qvideoprobe.cpp \
video/qabstractvideofilter.cpp \
- video/qvideoframeconversionhelper.cpp
+ video/qvideoframeconversionhelper.cpp \
+ video/qvideosurfaces.cpp
SSE2_SOURCES += video/qvideoframeconversionhelper_sse2.cpp
SSSE3_SOURCES += video/qvideoframeconversionhelper_ssse3.cpp
diff --git a/src/multimediawidgets/qgraphicsvideoitem.cpp b/src/multimediawidgets/qgraphicsvideoitem.cpp
index 2db8987fb..7c0521471 100644
--- a/src/multimediawidgets/qgraphicsvideoitem.cpp
+++ b/src/multimediawidgets/qgraphicsvideoitem.cpp
@@ -49,7 +49,7 @@
#include <QtCore/qpointer.h>
#if QT_CONFIG(opengl)
-#include <QtOpenGL/qgl.h>
+#include <QOpenGLContext>
#endif
QT_BEGIN_NAMESPACE
@@ -232,6 +232,22 @@ QMediaObject *QGraphicsVideoItem::mediaObject() const
}
/*!
+ \since 5.15
+ \property QGraphicsVideoItem::videoSurface
+ \brief Returns the underlying video surface that can render video frames
+ to the current item.
+ This property is never \c nullptr.
+ Example of how to render video frames to QGraphicsVideoItem:
+ \snippet multimedia-snippets/video.cpp GraphicsVideoItem Surface
+ \sa QMediaPlayer::setVideoOutput
+*/
+
+QAbstractVideoSurface *QGraphicsVideoItem::videoSurface() const
+{
+ return d_func()->surface;
+}
+
+/*!
\internal
*/
bool QGraphicsVideoItem::setMediaObject(QMediaObject *object)
@@ -379,7 +395,7 @@ void QGraphicsVideoItem::paint(
if (painter->paintEngine()->type() == QPaintEngine::OpenGL
|| painter->paintEngine()->type() == QPaintEngine::OpenGL2)
{
- d->surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
+ d->surface->updateGLContext();
if (d->surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
d->surface->setShaderType(QPainterVideoSurface::GlslShader);
} else {
diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h
index 5aa3bd75c..5c71ee651 100644
--- a/src/multimediawidgets/qgraphicsvideoitem.h
+++ b/src/multimediawidgets/qgraphicsvideoitem.h
@@ -60,11 +60,13 @@ class Q_MULTIMEDIAWIDGETS_EXPORT QGraphicsVideoItem : public QGraphicsObject, pu
Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
Q_PROPERTY(QSizeF size READ size WRITE setSize)
Q_PROPERTY(QSizeF nativeSize READ nativeSize NOTIFY nativeSizeChanged)
+ Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface CONSTANT)
public:
explicit QGraphicsVideoItem(QGraphicsItem *parent = nullptr);
~QGraphicsVideoItem();
QMediaObject *mediaObject() const override;
+ QAbstractVideoSurface *videoSurface() const;
Qt::AspectRatioMode aspectRatioMode() const;
void setAspectRatioMode(Qt::AspectRatioMode mode);
diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp
index 944ea23a7..5fe76d869 100644
--- a/src/multimediawidgets/qpaintervideosurface.cpp
+++ b/src/multimediawidgets/qpaintervideosurface.cpp
@@ -47,9 +47,9 @@
#include <private/qmediaopenglhelper_p.h>
#if QT_CONFIG(opengl)
-#include <qglshaderprogram.h>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLFunctions>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QOpenGLShaderProgram>
#include <QtGui/QWindow>
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
@@ -57,15 +57,6 @@
#ifndef GL_RGB8
#define GL_RGB8 0x8051
#endif
-
-static void makeCurrent(QGLContext *context)
-{
- context->makeCurrent();
-
- auto handle = context->contextHandle();
- if (handle && QOpenGLContext::currentContext() != handle)
- handle->makeCurrent(handle->surface());
-}
#endif
#include <QtDebug>
@@ -264,7 +255,7 @@ void QVideoSurfaceGenericPainter::updateColors(int, int, int, int)
class QVideoSurfaceGLPainter : public QVideoSurfacePainter, protected QOpenGLFunctions
{
public:
- QVideoSurfaceGLPainter(QGLContext *context);
+ QVideoSurfaceGLPainter(QOpenGLContext *context);
~QVideoSurfaceGLPainter();
QList<QVideoFrame::PixelFormat> supportedPixelFormats(
QAbstractVideoBuffer::HandleType handleType) const override;
@@ -292,17 +283,12 @@ protected:
|| format.pixelFormat() == QVideoFrame::Format_ARGB32);
}
-#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
- typedef void (APIENTRY *_glActiveTexture) (GLenum);
- _glActiveTexture glActiveTexture;
-#endif
-
QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
QList<QVideoFrame::PixelFormat> m_glPixelFormats;
QMatrix4x4 m_colorMatrix;
QVideoFrame m_frame;
- QGLContext *m_context;
+ QOpenGLContext *m_context;
QAbstractVideoBuffer::HandleType m_handleType;
QVideoSurfaceFormat::Direction m_scanLineDirection;
bool m_mirrored;
@@ -320,7 +306,7 @@ protected:
bool m_yuv;
};
-QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context)
+QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QOpenGLContext *context)
: m_context(context)
, m_handleType(QAbstractVideoBuffer::NoHandle)
, m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
@@ -332,10 +318,6 @@ QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context)
, m_textureCount(0)
, m_yuv(false)
{
-#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
- glActiveTexture = (_glActiveTexture)m_context->getProcAddress(QLatin1String("glActiveTexture"));
-#endif
-
memset(m_textureIds, 0, sizeof(m_textureIds));
memset(m_textureWidths, 0, sizeof(m_textureWidths));
memset(m_textureHeights, 0, sizeof(m_textureHeights));
@@ -404,8 +386,6 @@ QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVide
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
- makeCurrent(m_context);
-
for (int i = 0; i < m_textureCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
glTexImage2D(
@@ -680,7 +660,7 @@ static const char *qt_arbfp_ayuvShaderProgram =
class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter
{
public:
- QVideoSurfaceArbFpPainter(QGLContext *context);
+ QVideoSurfaceArbFpPainter(QOpenGLContext *context);
QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) override;
void stop() override;
@@ -707,20 +687,20 @@ private:
QSize m_frameSize;
};
-QVideoSurfaceArbFpPainter::QVideoSurfaceArbFpPainter(QGLContext *context)
+QVideoSurfaceArbFpPainter::QVideoSurfaceArbFpPainter(QOpenGLContext *context)
: QVideoSurfaceGLPainter(context)
, m_programId(0)
{
glProgramStringARB = (_glProgramStringARB) m_context->getProcAddress(
- QLatin1String("glProgramStringARB"));
+ QByteArray("glProgramStringARB"));
glBindProgramARB = (_glBindProgramARB) m_context->getProcAddress(
- QLatin1String("glBindProgramARB"));
+ QByteArray("glBindProgramARB"));
glDeleteProgramsARB = (_glDeleteProgramsARB) m_context->getProcAddress(
- QLatin1String("glDeleteProgramsARB"));
+ QByteArray("glDeleteProgramsARB"));
glGenProgramsARB = (_glGenProgramsARB) m_context->getProcAddress(
- QLatin1String("glGenProgramsARB"));
+ QByteArray("glGenProgramsARB"));
glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress(
- QLatin1String("glProgramLocalParameter4fARB"));
+ QByteArray("glProgramLocalParameter4fARB"));
m_imagePixelFormats
<< QVideoFrame::Format_RGB32
@@ -746,8 +726,6 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac
QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
- makeCurrent(m_context);
-
const char *program = 0;
if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
@@ -871,8 +849,6 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac
void QVideoSurfaceArbFpPainter::stop()
{
if (m_context) {
- makeCurrent(m_context);
-
if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
glDeleteTextures(m_textureCount, m_textureIds);
glDeleteProgramsARB(1, &m_programId);
@@ -1079,7 +1055,7 @@ static const char *qt_glsl_ayuvShaderProgram =
class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter
{
public:
- QVideoSurfaceGlslPainter(QGLContext *context);
+ QVideoSurfaceGlslPainter(QOpenGLContext *context);
QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) override;
void stop() override;
@@ -1088,11 +1064,11 @@ public:
const QRectF &target, QPainter *painter, const QRectF &source) override;
private:
- QGLShaderProgram m_program;
+ QOpenGLShaderProgram m_program;
QSize m_frameSize;
};
-QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QGLContext *context)
+QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QOpenGLContext *context)
: QVideoSurfaceGLPainter(context)
, m_program(context)
{
@@ -1100,7 +1076,7 @@ QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QGLContext *context)
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_ARGB32;
- if (!context->contextHandle()->isOpenGLES()) {
+ if (!context->isOpenGLES()) {
m_imagePixelFormats
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_BGR24;
@@ -1124,8 +1100,6 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
- makeCurrent(m_context);
-
const char *fragmentProgram = 0;
if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
@@ -1143,13 +1117,13 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
fragmentProgram = qt_glsl_argbShaderProgram;
break;
case QVideoFrame::Format_RGB24:
- if (!m_context->contextHandle()->isOpenGLES()) {
+ if (!m_context->isOpenGLES()) {
initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
fragmentProgram = qt_glsl_rgbShaderProgram;
}
break;
case QVideoFrame::Format_BGR24:
- if (!m_context->contextHandle()->isOpenGLES()) {
+ if (!m_context->isOpenGLES()) {
initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
fragmentProgram = qt_glsl_argbShaderProgram;
}
@@ -1202,11 +1176,11 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
if (!fragmentProgram) {
error = QAbstractVideoSurface::UnsupportedFormatError;
- } else if (!m_program.addShaderFromSourceCode(QGLShader::Vertex, qt_glsl_vertexShaderProgram)) {
+ } else if (!m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, qt_glsl_vertexShaderProgram)) {
qWarning("QPainterVideoSurface: Vertex shader compile error %s",
qPrintable(m_program.log()));
error = QAbstractVideoSurface::ResourceError;
- } else if (!m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentProgram)) {
+ } else if (!m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentProgram)) {
qWarning("QPainterVideoSurface: Shader compile error %s", qPrintable(m_program.log()));
error = QAbstractVideoSurface::ResourceError;
m_program.removeAllShaders();
@@ -1231,8 +1205,6 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
void QVideoSurfaceGlslPainter::stop()
{
if (m_context) {
- makeCurrent(m_context);
-
if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
glDeleteTextures(m_textureCount, m_textureIds);
}
@@ -1473,29 +1445,28 @@ void QPainterVideoSurface::stop()
bool QPainterVideoSurface::present(const QVideoFrame &frame)
{
if (!m_ready) {
- if (!isActive())
+ if (!isActive()) {
setError(StoppedError);
+ return false;
+ }
} else if (frame.isValid()
&& (frame.pixelFormat() != m_pixelFormat || frame.size() != m_frameSize)) {
setError(IncorrectFormatError);
stop();
+ return false;
} else {
QAbstractVideoSurface::Error error = m_painter->setCurrentFrame(frame);
-
if (error != QAbstractVideoSurface::NoError) {
setError(error);
-
stop();
- } else {
- m_ready = false;
-
- emit frameChanged();
-
- return true;
+ return false;
}
+
+ m_ready = false;
+ emit frameChanged();
}
- return false;
+ return true;
}
/*!
@@ -1612,35 +1583,33 @@ void QPainterVideoSurface::paint(QPainter *painter, const QRectF &target, const
/*!
*/
-const QGLContext *QPainterVideoSurface::glContext() const
+const QOpenGLContext *QPainterVideoSurface::glContext() const
{
return m_glContext;
}
/*!
*/
-void QPainterVideoSurface::setGLContext(QGLContext *context)
+void QPainterVideoSurface::updateGLContext()
{
- if (m_glContext == context)
+ auto oldContext = m_glContext;
+ m_glContext = QOpenGLContext::currentContext();
+ if (oldContext == m_glContext)
return;
- m_glContext = context;
-
m_shaderTypes = NoShaders;
if (m_glContext) {
//Set a dynamic property to access the OpenGL context
- this->setProperty("GLContext", QVariant::fromValue<QObject*>(m_glContext->contextHandle()));
-
- makeCurrent(m_glContext);
+ this->setProperty("GLContext", QVariant::fromValue<QObject *>(m_glContext));
const QByteArray extensions(reinterpret_cast<const char *>(
- context->contextHandle()->functions()->glGetString(GL_EXTENSIONS)));
+ m_glContext->functions()->glGetString(GL_EXTENSIONS)));
#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
if (extensions.contains("ARB_fragment_program"))
m_shaderTypes |= FragmentProgramShader;
#endif
- if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext)
+ if (QOpenGLShaderProgram::hasOpenGLShaderPrograms(m_glContext)
#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC)
&& extensions.contains("ARB_shader_objects")
#endif
@@ -1743,13 +1712,11 @@ void QPainterVideoSurface::createPainter()
#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
case FragmentProgramShader:
Q_ASSERT(m_glContext);
- makeCurrent(m_glContext);
m_painter = new QVideoSurfaceArbFpPainter(m_glContext);
break;
#endif // !QT_OPENGL_ES && !QT_OPENGL_DYNAMIC
case GlslShader:
Q_ASSERT(m_glContext);
- makeCurrent(m_glContext);
m_painter = new QVideoSurfaceGlslPainter(m_glContext);
break;
default:
diff --git a/src/multimediawidgets/qpaintervideosurface_p.h b/src/multimediawidgets/qpaintervideosurface_p.h
index 990d20cbe..582d6944c 100644
--- a/src/multimediawidgets/qpaintervideosurface_p.h
+++ b/src/multimediawidgets/qpaintervideosurface_p.h
@@ -59,11 +59,6 @@
#include <qabstractvideosurface.h>
#include <qvideoframe.h>
-QT_BEGIN_NAMESPACE
-
-class QGLContext;
-QT_END_NAMESPACE
-
QT_USE_NAMESPACE
QT_BEGIN_NAMESPACE
@@ -90,7 +85,7 @@ public:
virtual void viewportDestroyed() {}
};
-
+class QOpenGLContext;
class Q_AUTOTEST_EXPORT QPainterVideoSurface : public QAbstractVideoSurface
{
Q_OBJECT
@@ -126,8 +121,8 @@ public:
void paint(QPainter *painter, const QRectF &target, const QRectF &source = QRectF(0, 0, 1, 1));
#if QT_CONFIG(opengl)
- const QGLContext *glContext() const;
- void setGLContext(QGLContext *context);
+ const QOpenGLContext *glContext() const;
+ void updateGLContext();
enum ShaderType
{
@@ -155,7 +150,7 @@ private:
QVideoSurfacePainter *m_painter;
#if QT_CONFIG(opengl)
- QGLContext *m_glContext;
+ QOpenGLContext *m_glContext;
ShaderTypes m_shaderTypes;
ShaderType m_shaderType;
#endif
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp
index a7d3665f8..5158b2f35 100644
--- a/src/multimediawidgets/qvideowidget.cpp
+++ b/src/multimediawidgets/qvideowidget.cpp
@@ -145,7 +145,8 @@ QRendererVideoWidgetBackend::QRendererVideoWidgetBackend(
connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
this, SLOT(formatChanged(QVideoSurfaceFormat)));
- m_rendererControl->setSurface(m_surface);
+ if (m_rendererControl)
+ m_rendererControl->setSurface(m_surface);
}
QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
@@ -153,14 +154,21 @@ QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend()
delete m_surface;
}
+QAbstractVideoSurface *QRendererVideoWidgetBackend::videoSurface() const
+{
+ return m_surface;
+}
+
void QRendererVideoWidgetBackend::releaseControl()
{
- m_service->releaseControl(m_rendererControl);
+ if (m_service && m_rendererControl)
+ m_service->releaseControl(m_rendererControl);
}
void QRendererVideoWidgetBackend::clearSurface()
{
- m_rendererControl->setSurface(0);
+ if (m_rendererControl)
+ m_rendererControl->setSurface(0);
}
void QRendererVideoWidgetBackend::setBrightness(int brightness)
@@ -220,7 +228,6 @@ void QRendererVideoWidgetBackend::hideEvent(QHideEvent *)
{
#if QT_CONFIG(opengl)
m_updatePaintDevice = true;
- m_surface->setGLContext(0);
#endif
}
@@ -257,7 +264,7 @@ void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event)
|| painter.paintEngine()->type() == QPaintEngine::OpenGL2)) {
m_updatePaintDevice = false;
- m_surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
+ m_surface->updateGLContext();
if (m_surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
m_surface->setShaderType(QPainterVideoSurface::GlslShader);
} else {
@@ -469,7 +476,7 @@ void QVideoWidgetPrivate::clearService()
delete rendererBackend;
rendererBackend = 0;
- } else {
+ } else if (windowBackend) {
windowBackend->releaseControl();
delete windowBackend;
@@ -515,18 +522,15 @@ bool QVideoWidgetPrivate::createWindowBackend()
bool QVideoWidgetPrivate::createRendererBackend()
{
- if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) {
- if (QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(control)) {
- rendererBackend = new QRendererVideoWidgetBackend(service, rendererControl, q_func());
- currentBackend = rendererBackend;
-
- setCurrentControl(rendererBackend);
+ QMediaControl *control = service
+ ? service->requestControl(QVideoRendererControl_iid)
+ : nullptr;
+ rendererBackend = new QRendererVideoWidgetBackend(service,
+ qobject_cast<QVideoRendererControl *>(control), q_func());
+ currentBackend = rendererBackend;
+ setCurrentControl(rendererBackend);
- return true;
- }
- service->releaseControl(control);
- }
- return false;
+ return !service || (service && control);
}
void QVideoWidgetPrivate::_q_serviceDestroyed()
@@ -611,7 +615,7 @@ void QVideoWidgetPrivate::_q_dimensionsChanged()
The \a parent is passed to QWidget.
*/
QVideoWidget::QVideoWidget(QWidget *parent)
- : QWidget(parent, 0)
+ : QWidget(parent, {})
, d_ptr(new QVideoWidgetPrivate)
{
d_ptr->q_ptr = this;
@@ -621,7 +625,7 @@ QVideoWidget::QVideoWidget(QWidget *parent)
\internal
*/
QVideoWidget::QVideoWidget(QVideoWidgetPrivate &dd, QWidget *parent)
- : QWidget(parent, 0)
+ : QWidget(parent, {})
, d_ptr(&dd)
{
d_ptr->q_ptr = this;
@@ -696,6 +700,29 @@ bool QVideoWidget::setMediaObject(QMediaObject *object)
}
/*!
+ \since 5.15
+ \property QVideoWidget::videoSurface
+ \brief Returns the underlaying video surface that can render video frames
+ to the current widget.
+ This property is never \c nullptr.
+ Example of how to render video frames to QVideoWidget:
+ \snippet multimedia-snippets/video.cpp Widget Surface
+ \sa QMediaPlayer::setVideoOutput
+*/
+
+QAbstractVideoSurface *QVideoWidget::videoSurface() const
+{
+ auto d = const_cast<QVideoWidgetPrivate *>(d_func());
+
+ if (!d->rendererBackend) {
+ d->clearService();
+ d->createRendererBackend();
+ }
+
+ return d->rendererBackend->videoSurface();
+}
+
+/*!
\property QVideoWidget::aspectRatioMode
\brief how video is scaled with respect to its aspect ratio.
*/
diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h
index fff1153ca..fdf93330b 100644
--- a/src/multimediawidgets/qvideowidget.h
+++ b/src/multimediawidgets/qvideowidget.h
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
class QMediaObject;
class QVideoWidgetPrivate;
+class QAbstractVideoSurface;
class Q_MULTIMEDIAWIDGETS_EXPORT QVideoWidget : public QWidget, public QMediaBindableInterface
{
Q_OBJECT
@@ -62,12 +63,14 @@ class Q_MULTIMEDIAWIDGETS_EXPORT QVideoWidget : public QWidget, public QMediaBin
Q_PROPERTY(int contrast READ contrast WRITE setContrast NOTIFY contrastChanged)
Q_PROPERTY(int hue READ hue WRITE setHue NOTIFY hueChanged)
Q_PROPERTY(int saturation READ saturation WRITE setSaturation NOTIFY saturationChanged)
+ Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface CONSTANT)
public:
explicit QVideoWidget(QWidget *parent = nullptr);
~QVideoWidget();
QMediaObject *mediaObject() const override;
+ QAbstractVideoSurface *videoSurface() const;
#ifdef Q_QDOC
bool isFullScreen() const;
diff --git a/src/multimediawidgets/qvideowidget_p.h b/src/multimediawidgets/qvideowidget_p.h
index ef417b222..a3e687488 100644
--- a/src/multimediawidgets/qvideowidget_p.h
+++ b/src/multimediawidgets/qvideowidget_p.h
@@ -55,7 +55,7 @@
#include "qvideowidget.h"
#ifndef QT_NO_OPENGL
-#include <QGLWidget>
+#include <QOpenGLWidget>
#endif
#include "qpaintervideosurface_p.h"
@@ -131,6 +131,8 @@ public:
QRendererVideoWidgetBackend(QMediaService *service, QVideoRendererControl *control, QWidget *widget);
~QRendererVideoWidgetBackend();
+ QAbstractVideoSurface *videoSurface() const;
+
void releaseControl();
void clearSurface();
@@ -222,40 +224,21 @@ class QVideoWidgetPrivate
{
Q_DECLARE_PUBLIC(QVideoWidget)
public:
- QVideoWidgetPrivate()
- : q_ptr(0)
- , mediaObject(0)
- , service(0)
- , widgetBackend(0)
- , windowBackend(0)
- , rendererBackend(0)
- , currentControl(0)
- , currentBackend(0)
- , brightness(0)
- , contrast(0)
- , hue(0)
- , saturation(0)
- , aspectRatioMode(Qt::KeepAspectRatio)
- , nonFullScreenFlags(0)
- , wasFullScreen(false)
- {
- }
-
- QVideoWidget *q_ptr;
+ QVideoWidget *q_ptr = nullptr;
QPointer<QMediaObject> mediaObject;
- QMediaService *service;
- QVideoWidgetControlBackend *widgetBackend;
- QWindowVideoWidgetBackend *windowBackend;
- QRendererVideoWidgetBackend *rendererBackend;
- QVideoWidgetControlInterface *currentControl;
- QVideoWidgetBackend *currentBackend;
- int brightness;
- int contrast;
- int hue;
- int saturation;
- Qt::AspectRatioMode aspectRatioMode;
+ QMediaService *service = nullptr;
+ QVideoWidgetControlBackend *widgetBackend = nullptr;
+ QWindowVideoWidgetBackend *windowBackend = nullptr;
+ QRendererVideoWidgetBackend *rendererBackend = nullptr;
+ QVideoWidgetControlInterface *currentControl = nullptr;
+ QVideoWidgetBackend *currentBackend = nullptr;
+ int brightness = 0;
+ int contrast = 0;
+ int hue = 0;
+ int saturation = 0;
+ Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio;
Qt::WindowFlags nonFullScreenFlags;
- bool wasFullScreen;
+ bool wasFullScreen = false;
bool createWidgetBackend();
bool createWindowBackend();
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
index f3ad84836..a0f809376 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
@@ -53,7 +53,6 @@
#include <qdebug.h>
#include <qvideoframe.h>
#include <private/qmemoryvideobuffer_p.h>
-#include <private/qvideoframe_p.h>
#include <QtCore/private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
@@ -749,7 +748,7 @@ void QAndroidCameraSession::processPreviewImage(int id, const QVideoFrame &frame
transform.scale(-1, 1);
transform.rotate(rotation);
- emit imageCaptured(id, qt_imageFromVideoFrame(frame).transformed(transform));
+ emit imageCaptured(id, frame.image().transformed(transform));
}
void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame)
diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
index ef86af896..66eafc765 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
@@ -176,12 +176,12 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro
if (!string.isNull()) {
metadata.insert(isVideo ? QMediaMetaData::LeadPerformer
: QMediaMetaData::ContributingArtist,
- string.split('/', QString::SkipEmptyParts));
+ string.split('/', Qt::SkipEmptyParts));
}
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Author);
if (!string.isNull())
- metadata.insert(QMediaMetaData::Author, string.split('/', QString::SkipEmptyParts));
+ metadata.insert(QMediaMetaData::Author, string.split('/', Qt::SkipEmptyParts));
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Bitrate);
if (!string.isNull()) {
@@ -196,7 +196,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Composer);
if (!string.isNull())
- metadata.insert(QMediaMetaData::Composer, string.split('/', QString::SkipEmptyParts));
+ metadata.insert(QMediaMetaData::Composer, string.split('/', Qt::SkipEmptyParts));
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Date);
if (!string.isNull())
@@ -231,7 +231,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Writer);
if (!string.isNull())
- metadata.insert(QMediaMetaData::Writer, string.split('/', QString::SkipEmptyParts));
+ metadata.insert(QMediaMetaData::Writer, string.split('/', Qt::SkipEmptyParts));
string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Year);
if (!string.isNull())
diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
index f899481f0..de8422b86 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp
@@ -271,7 +271,7 @@ void AndroidMediaPlayer::setAudioRole(QAudio::Role role)
void AndroidMediaPlayer::setCustomAudioRole(const QString &role)
{
- QStringList roles = role.split(",", QString::SkipEmptyParts);
+ QStringList roles = role.split(",", Qt::SkipEmptyParts);
int type = 0; // CONTENT_TYPE_UNKNOWN
int usage = 0; // USAGE_UNKNOWN
diff --git a/src/plugins/avfoundation/camera/avfcameraservice.h b/src/plugins/avfoundation/camera/avfcameraservice.h
index 2969882b0..ec2884217 100644
--- a/src/plugins/avfoundation/camera/avfcameraservice.h
+++ b/src/plugins/avfoundation/camera/avfcameraservice.h
@@ -70,6 +70,7 @@ class AVFMediaRecorderControlIOS;
class AVFAudioEncoderSettingsControl;
class AVFVideoEncoderSettingsControl;
class AVFMediaContainerControl;
+class AVFCameraWindowControl;
class AVFCameraService : public QMediaService
{
@@ -120,6 +121,7 @@ private:
AVFAudioEncoderSettingsControl *m_audioEncoderSettingsControl;
AVFVideoEncoderSettingsControl *m_videoEncoderSettingsControl;
AVFMediaContainerControl *m_mediaContainerControl;
+ AVFCameraWindowControl *m_captureWindowControl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm
index 33b4b72aa..627ecf67c 100644
--- a/src/plugins/avfoundation/camera/avfcameraservice.mm
+++ b/src/plugins/avfoundation/camera/avfcameraservice.mm
@@ -61,6 +61,7 @@
#include "avfaudioencodersettingscontrol.h"
#include "avfvideoencodersettingscontrol.h"
#include "avfmediacontainercontrol.h"
+#include "avfcamerawindowcontrol.h"
#ifdef Q_OS_IOS
#include "avfcamerazoomcontrol.h"
@@ -74,7 +75,8 @@ QT_USE_NAMESPACE
AVFCameraService::AVFCameraService(QObject *parent):
QMediaService(parent),
- m_videoOutput(nullptr)
+ m_videoOutput(nullptr),
+ m_captureWindowControl(nullptr)
{
m_session = new AVFCameraSession(this);
m_cameraControl = new AVFCameraControl(this);
@@ -119,6 +121,12 @@ AVFCameraService::~AVFCameraService()
delete m_recorderControl;
#endif
+ if (m_captureWindowControl) {
+ m_session->setCapturePreviewOutput(nullptr);
+ delete m_captureWindowControl;
+ m_captureWindowControl = nullptr;
+ }
+
if (m_videoOutput) {
m_session->setVideoOutput(nullptr);
delete m_videoOutput;
@@ -210,6 +218,14 @@ QMediaControl *AVFCameraService::requestControl(const char *name)
return m_cameraZoomControl;
#endif
+ if (!m_captureWindowControl) {
+ if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+ m_captureWindowControl = new AVFCameraWindowControl(this);
+ m_session->setCapturePreviewOutput(m_captureWindowControl);
+ return m_captureWindowControl;
+ }
+ }
+
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0)
m_videoOutput = new AVFCameraRendererControl(this);
@@ -234,6 +250,11 @@ void AVFCameraService::releaseControl(QMediaControl *control)
delete m_videoOutput;
m_videoOutput = nullptr;
}
+ else if (m_captureWindowControl == control) {
+ m_session->setCapturePreviewOutput(nullptr);
+ delete m_captureWindowControl;
+ m_captureWindowControl = nullptr;
+ }
}
diff --git a/src/plugins/avfoundation/camera/avfcamerasession.h b/src/plugins/avfoundation/camera/avfcamerasession.h
index 103ec0e17..a449bb806 100644
--- a/src/plugins/avfoundation/camera/avfcamerasession.h
+++ b/src/plugins/avfoundation/camera/avfcamerasession.h
@@ -54,6 +54,7 @@ class AVFCameraControl;
class AVFCameraService;
class AVFCameraRendererControl;
class AVFMediaVideoProbeControl;
+class AVFCameraWindowControl;
struct AVFCameraInfo
{
@@ -79,6 +80,7 @@ public:
AVFCameraInfo activeCameraInfo() const { return m_activeCameraInfo; }
void setVideoOutput(AVFCameraRendererControl *output);
+ void setCapturePreviewOutput(AVFCameraWindowControl *output);
AVCaptureSession *captureSession() const { return m_captureSession; }
AVCaptureDevice *videoCaptureDevice() const;
@@ -122,6 +124,7 @@ private:
AVFCameraService *m_service;
AVFCameraRendererControl *m_videoOutput;
+ AVFCameraWindowControl *m_capturePreviewWindowOutput;
QCamera::State m_state;
bool m_active;
diff --git a/src/plugins/avfoundation/camera/avfcamerasession.mm b/src/plugins/avfoundation/camera/avfcamerasession.mm
index 3c5f8f09a..6ee9c2636 100644
--- a/src/plugins/avfoundation/camera/avfcamerasession.mm
+++ b/src/plugins/avfoundation/camera/avfcamerasession.mm
@@ -48,6 +48,7 @@
#include "avfcameraviewfindersettingscontrol.h"
#include "avfimageencodercontrol.h"
#include "avfcamerautility.h"
+#include "avfcamerawindowcontrol.h"
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
@@ -146,6 +147,7 @@ QList<AVFCameraInfo> AVFCameraSession::m_cameraDevices;
AVFCameraSession::AVFCameraSession(AVFCameraService *service, QObject *parent)
: QObject(parent)
, m_service(service)
+ , m_capturePreviewWindowOutput(nullptr)
, m_state(QCamera::UnloadedState)
, m_active(false)
, m_videoInput(nil)
@@ -160,6 +162,10 @@ AVFCameraSession::AVFCameraSession(AVFCameraService *service, QObject *parent)
AVFCameraSession::~AVFCameraSession()
{
+ if (m_capturePreviewWindowOutput) {
+ m_capturePreviewWindowOutput->setLayer(nil);
+ }
+
if (m_videoInput) {
[m_captureSession removeInput:m_videoInput];
[m_videoInput release];
@@ -257,6 +263,29 @@ void AVFCameraSession::setVideoOutput(AVFCameraRendererControl *output)
output->configureAVCaptureSession(this);
}
+void AVFCameraSession::setCapturePreviewOutput(AVFCameraWindowControl *output)
+{
+#ifdef QT_DEBUG_AVF
+ qDebug() << Q_FUNC_INFO << output;
+#endif
+
+ if (m_capturePreviewWindowOutput == output)
+ return;
+
+ if (m_capturePreviewWindowOutput)
+ m_capturePreviewWindowOutput->setLayer(nil);
+
+ m_capturePreviewWindowOutput = output;
+
+ if (m_capturePreviewWindowOutput) {
+ AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:m_captureSession];
+ m_capturePreviewWindowOutput->setLayer(previewLayer);
+ if (AVFCameraViewfinderSettingsControl2 *vfControl = m_service->viewfinderSettingsControl2()) {
+ m_capturePreviewWindowOutput->setNativeSize(vfControl->viewfinderSettings().resolution());
+ }
+ }
+}
+
AVCaptureDevice *AVFCameraSession::videoCaptureDevice() const
{
if (m_videoInput)
@@ -409,6 +438,10 @@ bool AVFCameraSession::applyViewfinderSettings()
}
vfControl->applySettings(vfSettings);
+
+ if (m_capturePreviewWindowOutput)
+ m_capturePreviewWindowOutput->setNativeSize(vfControl->viewfinderSettings().resolution());
+
return !vfSettings.isNull();
}
diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h
new file mode 100644
index 000000000..d1a950e38
--- /dev/null
+++ b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AVFCAMERAWINDOWCONTROL_H
+#define AVFCAMERAWINDOWCONTROL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QVideoWindowControl>
+
+@class AVCaptureVideoPreviewLayer;
+#if defined(Q_OS_MACOS)
+@class NSView;
+typedef NSView NativeView;
+#else
+@class UIView;
+typedef UIView NativeView;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class AVFCameraWindowControl : public QVideoWindowControl
+{
+ Q_OBJECT
+public:
+ AVFCameraWindowControl(QObject *parent = nullptr);
+ virtual ~AVFCameraWindowControl() override;
+
+ // QVideoWindowControl interface
+public:
+ WId winId() const override;
+ void setWinId(WId id) override;
+
+ QRect displayRect() const override;
+ void setDisplayRect(const QRect &rect) override;
+
+ bool isFullScreen() const override;
+ void setFullScreen(bool fullScreen) override;
+
+ void repaint() override;
+
+ QSize nativeSize() const override;
+
+ Qt::AspectRatioMode aspectRatioMode() const override;
+ void setAspectRatioMode(Qt::AspectRatioMode mode) override;
+
+ int brightness() const override;
+ void setBrightness(int brightness) override;
+
+ int contrast() const override;
+ void setContrast(int contrast) override;
+
+ int hue() const override;
+ void setHue(int hue) override;
+
+ int saturation() const override;
+ void setSaturation(int saturation) override;
+
+ // AVF Camera implementation details
+ void setNativeSize(QSize size);
+ void setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer);
+
+private:
+ void updateAspectRatio();
+ void updateCaptureLayerBounds();
+
+ void retainNativeLayer();
+ void releaseNativeLayer();
+
+ void attachNativeLayer();
+ void detachNativeLayer();
+
+ WId m_winId{0};
+ QRect m_displayRect;
+ bool m_fullscreen{false};
+ Qt::AspectRatioMode m_aspectRatioMode{Qt::IgnoreAspectRatio};
+ QSize m_nativeSize;
+ AVCaptureVideoPreviewLayer *m_captureLayer{nullptr};
+ NativeView *m_nativeView{nullptr};
+};
+
+QT_END_NAMESPACE
+
+#endif // AVFCAMERAWINDOWCONTROL_H
diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm
new file mode 100644
index 000000000..5154d0646
--- /dev/null
+++ b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "avfcamerawindowcontrol.h"
+
+#import <AVFoundation/AVFoundation.h>
+#import <QuartzCore/CATransaction.h>
+
+#if QT_HAS_INCLUDE(<AppKit/AppKit.h>)
+#import <AppKit/AppKit.h>
+#endif
+
+#if QT_HAS_INCLUDE(<UIKit/UIKit.h>)
+#import <UIKit/UIKit.h>
+#endif
+
+QT_USE_NAMESPACE
+
+AVFCameraWindowControl::AVFCameraWindowControl(QObject *parent)
+ : QVideoWindowControl(parent)
+{
+ setObjectName(QStringLiteral("AVFCameraWindowControl"));
+}
+
+AVFCameraWindowControl::~AVFCameraWindowControl()
+{
+ releaseNativeLayer();
+}
+
+WId AVFCameraWindowControl::winId() const
+{
+ return m_winId;
+}
+
+void AVFCameraWindowControl::setWinId(WId id)
+{
+ if (m_winId == id)
+ return;
+
+ m_winId = id;
+
+ detachNativeLayer();
+ m_nativeView = (NativeView*)m_winId;
+ attachNativeLayer();
+}
+
+QRect AVFCameraWindowControl::displayRect() const
+{
+ return m_displayRect;
+}
+
+void AVFCameraWindowControl::setDisplayRect(const QRect &rect)
+{
+ if (m_displayRect != rect) {
+ m_displayRect = rect;
+ updateCaptureLayerBounds();
+ }
+}
+
+bool AVFCameraWindowControl::isFullScreen() const
+{
+ return m_fullscreen;
+}
+
+void AVFCameraWindowControl::setFullScreen(bool fullscreen)
+{
+ if (m_fullscreen != fullscreen) {
+ m_fullscreen = fullscreen;
+ Q_EMIT fullScreenChanged(fullscreen);
+ }
+}
+
+void AVFCameraWindowControl::repaint()
+{
+ if (m_captureLayer)
+ [m_captureLayer setNeedsDisplay];
+}
+
+QSize AVFCameraWindowControl::nativeSize() const
+{
+ return m_nativeSize;
+}
+
+void AVFCameraWindowControl::setNativeSize(QSize size)
+{
+ if (m_nativeSize != size) {
+ m_nativeSize = size;
+ Q_EMIT nativeSizeChanged();
+ }
+}
+
+Qt::AspectRatioMode AVFCameraWindowControl::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void AVFCameraWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ if (m_aspectRatioMode != mode) {
+ m_aspectRatioMode = mode;
+ updateAspectRatio();
+ }
+}
+
+int AVFCameraWindowControl::brightness() const
+{
+ return 0;
+}
+
+void AVFCameraWindowControl::setBrightness(int brightness)
+{
+ if (0 != brightness)
+ qWarning("AVFCameraWindowControl doesn't support changing Brightness");
+}
+
+int AVFCameraWindowControl::contrast() const
+{
+ return 0;
+}
+
+void AVFCameraWindowControl::setContrast(int contrast)
+{
+ if (0 != contrast)
+ qWarning("AVFCameraWindowControl doesn't support changing Contrast");
+}
+
+int AVFCameraWindowControl::hue() const
+{
+ return 0;
+}
+
+void AVFCameraWindowControl::setHue(int hue)
+{
+ if (0 != hue)
+ qWarning("AVFCameraWindowControl doesn't support changing Hue");
+}
+
+int AVFCameraWindowControl::saturation() const
+{
+ return 0;
+}
+
+void AVFCameraWindowControl::setSaturation(int saturation)
+{
+ if (0 != saturation)
+ qWarning("AVFCameraWindowControl doesn't support changing Saturation");
+}
+
+void AVFCameraWindowControl::setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer)
+{
+ if (m_captureLayer == capturePreviewLayer)
+ return;
+
+ releaseNativeLayer();
+
+ m_captureLayer = capturePreviewLayer;
+
+ if (m_captureLayer)
+ retainNativeLayer();
+}
+
+void AVFCameraWindowControl::updateAspectRatio()
+{
+ if (m_captureLayer) {
+ switch (m_aspectRatioMode) {
+ case Qt::IgnoreAspectRatio:
+ [m_captureLayer setVideoGravity:AVLayerVideoGravityResize];
+ break;
+ case Qt::KeepAspectRatio:
+ [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void AVFCameraWindowControl::updateCaptureLayerBounds()
+{
+ if (m_captureLayer && m_nativeView) {
+ [CATransaction begin];
+ [CATransaction setDisableActions: YES]; // disable animation/flicks
+ m_captureLayer.frame = m_displayRect.toCGRect();
+ [CATransaction commit];
+ }
+}
+
+void AVFCameraWindowControl::retainNativeLayer()
+{
+ [m_captureLayer retain];
+
+ updateAspectRatio();
+ attachNativeLayer();
+}
+
+void AVFCameraWindowControl::releaseNativeLayer()
+{
+ if (m_captureLayer) {
+ detachNativeLayer();
+ [m_captureLayer release];
+ m_captureLayer = nullptr;
+ }
+}
+
+void AVFCameraWindowControl::attachNativeLayer()
+{
+ if (m_captureLayer && m_nativeView) {
+#if defined(Q_OS_MACOS)
+ m_nativeView.wantsLayer = YES;
+#endif
+ CALayer *nativeLayer = m_nativeView.layer;
+ [nativeLayer addSublayer:m_captureLayer];
+ updateCaptureLayerBounds();
+ }
+}
+
+void AVFCameraWindowControl::detachNativeLayer()
+{
+ if (m_captureLayer && m_nativeView)
+ [m_captureLayer removeFromSuperlayer];
+}
+
+#include "moc_avfcamerawindowcontrol.cpp"
diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm
index dbaf3ed41..55a20b1bd 100644
--- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm
+++ b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm
@@ -48,7 +48,6 @@
#include <QtCore/qbuffer.h>
#include <QtConcurrent/qtconcurrentrun.h>
#include <QtGui/qimagereader.h>
-#include <private/qvideoframe_p.h>
QT_USE_NAMESPACE
@@ -214,7 +213,7 @@ void AVFImageCaptureControl::makeCapturePreview(CaptureRequest request,
QTransform transform;
transform.rotate(rotation);
- Q_EMIT imageCaptured(request.captureId, qt_imageFromVideoFrame(frame).transformed(transform));
+ Q_EMIT imageCaptured(request.captureId, frame.image().transformed(transform));
request.previewReady->release();
}
diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro
index 4b960ed5a..70caf7536 100644
--- a/src/plugins/avfoundation/camera/camera.pro
+++ b/src/plugins/avfoundation/camera/camera.pro
@@ -42,7 +42,8 @@ HEADERS += \
avfcameraflashcontrol.h \
avfvideoencodersettingscontrol.h \
avfmediacontainercontrol.h \
- avfaudioencodersettingscontrol.h
+ avfaudioencodersettingscontrol.h \
+ avfcamerawindowcontrol.h
OBJECTIVE_SOURCES += \
avfcameraserviceplugin.mm \
@@ -65,7 +66,8 @@ OBJECTIVE_SOURCES += \
avfcameraflashcontrol.mm \
avfvideoencodersettingscontrol.mm \
avfmediacontainercontrol.mm \
- avfaudioencodersettingscontrol.mm
+ avfaudioencodersettingscontrol.mm \
+ avfcamerawindowcontrol.mm
osx {
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
index 7a268a3d9..db29e88aa 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
@@ -67,7 +67,7 @@ public:
QMediaPlayer::MediaStatus mediaStatus() const;
QMediaContent media() const;
- const QIODevice *mediaStream() const;
+ QIODevice *mediaStream() const;
void setMedia(const QMediaContent &content, QIODevice *stream);
qint64 position() const;
@@ -110,6 +110,9 @@ public Q_SLOTS:
void processDurationChange(qint64 duration);
+ void streamReady();
+ void streamDestroyed();
+
Q_SIGNALS:
void positionChanged(qint64 position);
void durationChanged(qint64 duration);
@@ -128,6 +131,7 @@ private:
void setAudioAvailable(bool available);
void setVideoAvailable(bool available);
void setSeekable(bool seekable);
+ void resetStream(QIODevice *stream = nullptr);
AVFMediaPlayerService *m_service;
AVFVideoOutput *m_videoOutput;
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
index ba902a53c..424f30008 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
@@ -42,6 +42,7 @@
#include "avfvideooutput.h"
#include <qpointer.h>
+#include <QFileInfo>
#import <AVFoundation/AVFoundation.h>
@@ -66,7 +67,7 @@ static void *AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext = &AVFMedi
static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext;
static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext = &AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext;
-@interface AVFMediaPlayerSessionObserver : NSObject
+@interface AVFMediaPlayerSessionObserver : NSObject<AVAssetResourceLoaderDelegate>
@property (readonly, getter=player) AVPlayer* m_player;
@property (readonly, getter=playerItem) AVPlayerItem* m_playerItem;
@@ -74,7 +75,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
@property (readonly, getter=session) AVFMediaPlayerSession* m_session;
- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session;
-- (void) setURL:(NSURL *)url;
+- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType;
- (void) unloadMedia;
- (void) prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys;
- (void) assetFailedToPrepareForPlayback:(NSError *)error;
@@ -84,6 +85,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
change:(NSDictionary *)change context:(void *)context;
- (void) detatchSession;
- (void) dealloc;
+- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest;
@end
@implementation AVFMediaPlayerSessionObserver
@@ -95,6 +97,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
AVPlayerLayer *m_playerLayer;
NSURL *m_URL;
BOOL m_bufferIsLikelyToKeepUp;
+ NSData *m_data;
+ NSString *m_mimeType;
}
@synthesize m_player, m_playerItem, m_playerLayer, m_session;
@@ -109,8 +113,11 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
return self;
}
-- (void) setURL:(NSURL *)url
+- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType
{
+ [m_mimeType release];
+ m_mimeType = [mimeType retain];
+
if (m_URL != url)
{
[m_URL release];
@@ -122,6 +129,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
// use __block to avoid maintaining strong references on variables captured by the
// following block callback
__block AVURLAsset *asset = [[AVURLAsset URLAssetWithURL:m_URL options:nil] retain];
+ [asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()];
+
__block NSArray *requestedKeys = [[NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil] retain];
__block AVFMediaPlayerSessionObserver *blockSelf = self;
@@ -403,9 +412,48 @@ static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext
[m_URL release];
}
+ [m_mimeType release];
[super dealloc];
}
+- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
+{
+ Q_UNUSED(resourceLoader);
+
+ if (![loadingRequest.request.URL.scheme isEqualToString:@"iodevice"])
+ return NO;
+
+ QIODevice *device = m_session->mediaStream();
+ if (!device)
+ return NO;
+
+ device->seek(loadingRequest.dataRequest.requestedOffset);
+ if (loadingRequest.contentInformationRequest) {
+ loadingRequest.contentInformationRequest.contentType = m_mimeType;
+ loadingRequest.contentInformationRequest.contentLength = device->size();
+ loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
+ }
+
+ if (loadingRequest.dataRequest) {
+ NSInteger requestedLength = loadingRequest.dataRequest.requestedLength;
+ int maxBytes = qMin(32 * 1064, int(requestedLength));
+ char buffer[maxBytes];
+ NSInteger submitted = 0;
+ while (submitted < requestedLength) {
+ qint64 len = device->read(buffer, maxBytes);
+ if (len < 1)
+ break;
+
+ [loadingRequest.dataRequest respondWithData:[NSData dataWithBytes:buffer length:len]];
+ submitted += len;
+ }
+
+ // Finish loading even if not all bytes submitted.
+ [loadingRequest finishLoading];
+ }
+
+ return YES;
+}
@end
AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent)
@@ -483,11 +531,23 @@ QMediaContent AVFMediaPlayerSession::media() const
return m_resources;
}
-const QIODevice *AVFMediaPlayerSession::mediaStream() const
+QIODevice *AVFMediaPlayerSession::mediaStream() const
{
return m_mediaStream;
}
+static void setURL(void *observer, const QString &url, const QString &mimeType = QString())
+{
+ NSString *urlString = [NSString stringWithUTF8String:url.toUtf8().constData()];
+ NSURL *nsurl = [NSURL URLWithString:urlString];
+ [static_cast<AVFMediaPlayerSessionObserver*>(observer) setURL:nsurl mimeType:[NSString stringWithUTF8String:mimeType.toLatin1().constData()]];
+}
+
+static void setStreamURL(void *observer, const QString &url)
+{
+ setURL(observer, QLatin1String("iodevice://") + url, QFileInfo(url).suffix());
+}
+
void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
{
#ifdef QT_DEBUG_AVF
@@ -497,7 +557,7 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) unloadMedia];
m_resources = content;
- m_mediaStream = stream;
+ resetStream(stream);
setAudioAvailable(false);
setVideoAvailable(false);
@@ -508,7 +568,7 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
const QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
const QMediaPlayer::State oldState = m_state;
- if (content.isNull() || content.request().url().isEmpty()) {
+ if (!m_mediaStream && (content.isNull() || content.request().url().isEmpty())) {
m_mediaStatus = QMediaPlayer::NoMedia;
if (m_mediaStatus != oldMediaStatus)
Q_EMIT mediaStatusChanged(m_mediaStatus);
@@ -524,11 +584,16 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
if (m_mediaStatus != oldMediaStatus)
Q_EMIT mediaStatusChanged(m_mediaStatus);
- //Load AVURLAsset
- //initialize asset using content's URL
- NSString *urlString = [NSString stringWithUTF8String:content.request().url().toEncoded().constData()];
- NSURL *url = [NSURL URLWithString:urlString];
- [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) setURL:url];
+ if (m_mediaStream) {
+ // If there is a data, try to load it,
+ // otherwise wait for readyRead.
+ if (m_mediaStream->size())
+ setStreamURL(m_observer, m_resources.request().url().toString());
+ } else {
+ //Load AVURLAsset
+ //initialize asset using content's URL
+ setURL(m_observer, m_resources.request().url().toString());
+ }
m_state = QMediaPlayer::StoppedState;
if (m_state != oldState)
@@ -969,3 +1034,28 @@ void AVFMediaPlayerSession::processMediaLoadError()
Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media"));
}
+
+void AVFMediaPlayerSession::streamReady()
+{
+ setStreamURL(m_observer, m_resources.request().url().toString());
+}
+
+void AVFMediaPlayerSession::streamDestroyed()
+{
+ resetStream(nullptr);
+}
+
+void AVFMediaPlayerSession::resetStream(QIODevice *stream)
+{
+ if (m_mediaStream) {
+ disconnect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady);
+ disconnect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed);
+ }
+
+ m_mediaStream = stream;
+
+ if (m_mediaStream) {
+ connect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady);
+ connect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed);
+ }
+}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
index e06ddc4b0..63bdee4f5 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm
@@ -177,7 +177,11 @@ void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
#endif
//Check for needed formats to render as OpenGL Texture
- m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32);
+ auto handleGlEnabled = [this] {
+ m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32);
+ };
+ handleGlEnabled();
+ connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, this, handleGlEnabled);
//If we already have a layer, but changed surfaces start rendering again
if (m_playerLayer && !m_displayLink->isActive()) {
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index a0c120816..cee3e9c56 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -44,7 +44,6 @@
#include <QtMultimedia/qvideosurfaceformat.h>
#include <QtMultimedia/qcameraimagecapture.h>
#include <private/qmemoryvideobuffer_p.h>
-#include <private/qvideoframe_p.h>
#include "dscamerasession.h"
#include "dsvideorenderer.h"
@@ -637,7 +636,7 @@ void DSCameraSession::presentFrame()
if (m_capturedFrame.isValid()) {
- captureImage = qt_imageFromVideoFrame(m_capturedFrame);
+ captureImage = m_capturedFrame.image();
const bool needsVerticalMirroring = m_previewSurfaceFormat.scanLineDirection() != QVideoSurfaceFormat::TopToBottom;
captureImage = captureImage.mirrored(m_needsHorizontalMirroring, needsVerticalMirroring); // also causes a deep copy of the data
diff --git a/src/plugins/gstreamer/camerabin/camerabinzoom.cpp b/src/plugins/gstreamer/camerabin/camerabinzoom.cpp
index bb3659493..401e13207 100644
--- a/src/plugins/gstreamer/camerabin/camerabinzoom.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinzoom.cpp
@@ -51,7 +51,9 @@ CameraBinZoom::CameraBinZoom(CameraBinSession *session)
, m_requestedOpticalZoom(1.0)
, m_requestedDigitalZoom(1.0)
{
-
+ GstElement *camerabin = m_session->cameraBin();
+ g_signal_connect(G_OBJECT(camerabin), "notify::zoom", G_CALLBACK(updateZoom), this);
+ g_signal_connect(G_OBJECT(camerabin), "notify::max-zoom", G_CALLBACK(updateMaxZoom), this);
}
CameraBinZoom::~CameraBinZoom()
@@ -114,4 +116,32 @@ void CameraBinZoom::zoomTo(qreal optical, qreal digital)
emit currentDigitalZoomChanged(digital);
}
+void CameraBinZoom::updateZoom(GObject *o, GParamSpec *p, gpointer d)
+{
+ Q_UNUSED(p);
+
+ gfloat zoomFactor = 1.0;
+ g_object_get(o, ZOOM_PROPERTY, &zoomFactor, NULL);
+
+ CameraBinZoom *zoom = reinterpret_cast<CameraBinZoom *>(d);
+
+ QMetaObject::invokeMethod(zoom, "currentDigitalZoomChanged",
+ Qt::QueuedConnection,
+ Q_ARG(qreal, zoomFactor));
+}
+
+void CameraBinZoom::updateMaxZoom(GObject *o, GParamSpec *p, gpointer d)
+{
+ Q_UNUSED(p);
+
+ gfloat zoomFactor = 1.0;
+ g_object_get(o, MAX_ZOOM_PROPERTY, &zoomFactor, NULL);
+
+ CameraBinZoom *zoom = reinterpret_cast<CameraBinZoom *>(d);
+
+ QMetaObject::invokeMethod(zoom, "maximumDigitalZoomChanged",
+ Qt::QueuedConnection,
+ Q_ARG(qreal, zoomFactor));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinzoom.h b/src/plugins/gstreamer/camerabin/camerabinzoom.h
index 8ad4764b2..858ada2da 100644
--- a/src/plugins/gstreamer/camerabin/camerabinzoom.h
+++ b/src/plugins/gstreamer/camerabin/camerabinzoom.h
@@ -41,6 +41,7 @@
#define CAMERABINZOOMCONTROL_H
#include <qcamerazoomcontrol.h>
+#include <gst/gst.h>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,9 @@ public:
void zoomTo(qreal optical, qreal digital) override;
private:
+ static void updateZoom(GObject *o, GParamSpec *p, gpointer d);
+ static void updateMaxZoom(GObject *o, GParamSpec *p, gpointer d);
+
CameraBinSession *m_session;
qreal m_requestedOpticalZoom;
qreal m_requestedDigitalZoom;
diff --git a/src/plugins/m3u/qm3uhandler.cpp b/src/plugins/m3u/qm3uhandler.cpp
index 017c32d92..5e05994ef 100644
--- a/src/plugins/m3u/qm3uhandler.cpp
+++ b/src/plugins/m3u/qm3uhandler.cpp
@@ -163,7 +163,7 @@ public:
virtual bool writeItem(const QMediaContent& item)
{
- *m_textStream << item.request().url().toString() << endl;
+ *m_textStream << item.request().url().toString() << Qt::endl;
return true;
}
diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
index 32166502d..ca3a4b2ea 100644
--- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
@@ -138,6 +138,7 @@ QDeclarativeVideoOutput::QDeclarativeVideoOutput(QQuickItem *parent) :
{
initResource();
setFlag(ItemHasContents, true);
+ createBackend(nullptr);
}
QDeclarativeVideoOutput::~QDeclarativeVideoOutput()
@@ -148,6 +149,23 @@ QDeclarativeVideoOutput::~QDeclarativeVideoOutput()
}
/*!
+ \qmlproperty object QtMultimedia::VideoOutput::videoSurface
+ \since 5.15
+
+ This property holds the underlaying video surface that can be used
+ to render the video frames to this VideoOutput element.
+ It is similar to setting a QObject with \c videoSurface property as a source,
+ where this video surface will be set.
+
+ \sa source
+*/
+
+QAbstractVideoSurface *QDeclarativeVideoOutput::videoSurface() const
+{
+ return m_backend ? m_backend->videoSurface() : nullptr;
+}
+
+/*!
\qmlproperty variant QtMultimedia::VideoOutput::source
This property holds the source item providing the video frames like MediaPlayer or Camera.
@@ -206,21 +224,10 @@ void QDeclarativeVideoOutput::setSource(QObject *source)
}
m_sourceType = MediaObjectSource;
-#if QT_CONFIG(opengl)
} else if (metaObject->indexOfProperty("videoSurface") != -1) {
- // Make sure our backend is a QDeclarativeVideoRendererBackend
- m_backend.reset();
- createBackend(0);
- Q_ASSERT(m_backend);
-#ifndef QT_NO_DYNAMIC_CAST
- Q_ASSERT(dynamic_cast<QDeclarativeVideoRendererBackend *>(m_backend.data()));
-#endif
- QAbstractVideoSurface * const surface = m_backend->videoSurface();
- Q_ASSERT(surface);
m_source.data()->setProperty("videoSurface",
- QVariant::fromValue<QAbstractVideoSurface*>(surface));
+ QVariant::fromValue<QAbstractVideoSurface *>(videoSurface()));
m_sourceType = VideoSurfaceSource;
-#endif
} else {
m_sourceType = NoSource;
}
@@ -242,7 +249,8 @@ bool QDeclarativeVideoOutput::createBackend(QMediaService *service)
const auto instances = videoBackendFactoryLoader()->instances(QLatin1String("declarativevideobackend"));
for (QObject *instance : instances) {
if (QDeclarativeVideoBackendFactoryInterface *plugin = qobject_cast<QDeclarativeVideoBackendFactoryInterface*>(instance)) {
- m_backend.reset(plugin->create(this));
+ if (!m_backend)
+ m_backend.reset(plugin->create(this));
if (m_backend && m_backend->init(service)) {
backendAvailable = true;
break;
@@ -251,7 +259,8 @@ bool QDeclarativeVideoOutput::createBackend(QMediaService *service)
}
#if QT_CONFIG(opengl)
if (!backendAvailable) {
- m_backend.reset(new QDeclarativeVideoRendererBackend(this));
+ if (!m_backend)
+ m_backend.reset(new QDeclarativeVideoRendererBackend(this));
if (m_backend->init(service))
backendAvailable = true;
}
@@ -293,9 +302,6 @@ void QDeclarativeVideoOutput::_q_updateMediaObject()
if (m_mediaObject.data() == mediaObject)
return;
- if (m_sourceType != VideoSurfaceSource)
- m_backend.reset();
-
m_mediaObject.clear();
m_service.clear();
diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
index 8ea0dc338..d14731c91 100644
--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
@@ -67,6 +67,7 @@ class QMediaObject;
class QMediaService;
class QDeclarativeVideoBackend;
class QVideoOutputOrientationHandler;
+class QAbstractVideoSurface;
class Q_MULTIMEDIAQUICK_EXPORT QDeclarativeVideoOutput : public QQuickItem
{
@@ -80,6 +81,7 @@ class Q_MULTIMEDIAQUICK_EXPORT QDeclarativeVideoOutput : public QQuickItem
Q_PROPERTY(QRectF contentRect READ contentRect NOTIFY contentRectChanged)
Q_PROPERTY(QQmlListProperty<QAbstractVideoFilter> filters READ filters);
Q_PROPERTY(FlushMode flushMode READ flushMode WRITE setFlushMode NOTIFY flushModeChanged REVISION 13)
+ Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface CONSTANT REVISION 15)
Q_ENUMS(FlushMode)
Q_ENUMS(FillMode)
@@ -102,6 +104,8 @@ public:
QDeclarativeVideoOutput(QQuickItem *parent = 0);
~QDeclarativeVideoOutput();
+ QAbstractVideoSurface *videoSurface() const;
+
QObject *source() const { return m_source.data(); }
void setSource(QObject *source);
diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp
index 863cefa4e..bdfa23dfb 100644
--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp
+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp
@@ -46,7 +46,6 @@
#include <QtCore/qloggingcategory.h>
#include <private/qmediapluginloader_p.h>
#include <private/qsgvideonode_p.h>
-#include <private/qvideoframe_p.h>
#include <QtGui/QOpenGLContext>
#include <QtQuick/QQuickWindow>
@@ -304,7 +303,7 @@ QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode,
if (!runnable)
continue;
- QVideoFilterRunnable::RunFlags flags = 0;
+ QVideoFilterRunnable::RunFlags flags;
if (i == m_filters.count() - 1)
flags |= QVideoFilterRunnable::LastInChain;
@@ -363,7 +362,7 @@ QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode,
videoNode->setTexturedRectGeometry(m_renderedRect, m_sourceTextureRect,
qNormalizedOrientation(q->orientation()));
if (m_frameChanged) {
- QSGVideoNode::FrameFlags flags = 0;
+ QSGVideoNode::FrameFlags flags;
if (isFrameModified)
flags |= QSGVideoNode::FrameFiltered;
videoNode->setCurrentFrame(m_frame, flags);
@@ -372,7 +371,7 @@ QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode,
|| q->flushMode() == QDeclarativeVideoOutput::LastFrame) {
m_frameOnFlush = m_surfaceFormat.handleType() == QAbstractVideoBuffer::NoHandle
? m_frame
- : qt_imageFromVideoFrame(m_frame);
+ : m_frame.image();
}
//don't keep the frame for more than really necessary
diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
index 894486230..068b30653 100644
--- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
+++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
@@ -49,7 +49,6 @@
#include <qcameraimagecapture.h>
#include <qvideorenderercontrol.h>
#include <private/qmediaserviceprovider_p.h>
-#include <private/qvideoframe_p.h>
QT_USE_NAMESPACE
@@ -215,7 +214,7 @@ void tst_QCameraBackend::testCameraStates()
QCamera camera;
QCameraImageCapture imageCapture(&camera);
- QSignalSpy errorSignal(&camera, SIGNAL(error(QCamera::Error)));
+ QSignalSpy errorSignal(&camera, SIGNAL(errorOccurred(QCamera::Error)));
QSignalSpy stateChangedSignal(&camera, SIGNAL(stateChanged(QCamera::State)));
QSignalSpy statusChangedSignal(&camera, SIGNAL(statusChanged(QCamera::Status)));
@@ -263,8 +262,8 @@ void tst_QCameraBackend::testCameraStartError()
{
QCamera camera1(QCameraInfo::defaultCamera());
QCamera camera2(QCameraInfo::defaultCamera());
- QSignalSpy errorSpy1(&camera1, QOverload<QCamera::Error>::of(&QCamera::error));
- QSignalSpy errorSpy2(&camera2, QOverload<QCamera::Error>::of(&QCamera::error));
+ QSignalSpy errorSpy1(&camera1, &QCamera::errorOccurred);
+ QSignalSpy errorSpy2(&camera2, &QCamera::errorOccurred);
camera1.start();
camera2.start();
@@ -284,7 +283,7 @@ void tst_QCameraBackend::testCaptureMode()
{
QCamera camera;
- QSignalSpy errorSignal(&camera, SIGNAL(error(QCamera::Error)));
+ QSignalSpy errorSignal(&camera, SIGNAL(errorOccurred(QCamera::Error)));
QSignalSpy stateChangedSignal(&camera, SIGNAL(stateChanged(QCamera::State)));
QSignalSpy captureModeSignal(&camera, SIGNAL(captureModeChanged(QCamera::CaptureModes)));
@@ -451,7 +450,7 @@ void tst_QCameraBackend::testCaptureToBuffer()
QCOMPARE(imageAvailableSignal.first().first().toInt(), id);
QVideoFrame frame = imageAvailableSignal.first().last().value<QVideoFrame>();
- QVERIFY(!qt_imageFromVideoFrame(frame).isNull());
+ QVERIFY(!frame.image().isNull());
frame = QVideoFrame();
capturedSignal.clear();
@@ -509,7 +508,7 @@ void tst_QCameraBackend::testCaptureToBuffer()
QCOMPARE(imageAvailableSignal.first().first().toInt(), id);
frame = imageAvailableSignal.first().last().value<QVideoFrame>();
- QVERIFY(!qt_imageFromVideoFrame(frame).isNull());
+ QVERIFY(!frame.image().isNull());
QString fileName = savedSignal.first().last().toString();
QVERIFY(QFileInfo(fileName).exists());
@@ -632,7 +631,7 @@ void tst_QCameraBackend::testVideoRecording()
QMediaRecorder recorder(camera.data());
- QSignalSpy errorSignal(camera.data(), SIGNAL(error(QCamera::Error)));
+ QSignalSpy errorSignal(camera.data(), SIGNAL(errorOccurred(QCamera::Error)));
QSignalSpy recorderErrorSignal(&recorder, SIGNAL(error(QMediaRecorder::Error)));
QSignalSpy recorderStatusSignal(&recorder, SIGNAL(statusChanged(QMediaRecorder::Status)));
diff --git a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
index 798b63f96..27c7d85de 100644
--- a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
+++ b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp
@@ -32,6 +32,7 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
+#include <QQuickView>
#include "private/qdeclarativevideooutput_p.h"
@@ -109,6 +110,7 @@ private slots:
void flushMode();
void orientation();
void surfaceSource();
+ void paintSurface();
void sourceRect();
void contentRect();
@@ -349,6 +351,45 @@ void tst_QDeclarativeVideoOutput::surfaceSource()
delete videoOutput2;
}
+static const uchar rgb32ImageData[] =
+{// B G R A
+ 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff,
+ 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff
+};
+
+void tst_QDeclarativeVideoOutput::paintSurface()
+{
+ QQuickView window;
+ window.setSource(QUrl("qrc:/main.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ auto videoOutput = qobject_cast<QDeclarativeVideoOutput *>(window.rootObject());
+ QVERIFY(videoOutput);
+
+ auto surface = videoOutput->property("videoSurface").value<QAbstractVideoSurface *>();
+ QVERIFY(surface);
+ QVERIFY(!surface->isActive());
+ videoOutput->setSize(QSize(2, 2));
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+ QVERIFY(surface->isFormatSupported(format));
+ QVERIFY(surface->start(format));
+ QVERIFY(surface->isActive());
+
+ QImage img(rgb32ImageData, 2, 2, 8, QImage::Format_RGB32);
+ QVERIFY(surface->present(img));
+
+ if (QGuiApplication::platformName() == QLatin1String("offscreen")
+ || QGuiApplication::platformName() == QLatin1String("minimal"))
+ return;
+
+ QImage capture = window.grabWindow();
+ QCOMPARE(capture.pixelColor(0, 0), QColor(rgb32ImageData[2], rgb32ImageData[1], rgb32ImageData[0], rgb32ImageData[3]));
+ QCOMPARE(capture.pixelColor(1, 0), QColor(rgb32ImageData[6], rgb32ImageData[5], rgb32ImageData[4], rgb32ImageData[7]));
+ QCOMPARE(capture.pixelColor(0, 1), QColor(rgb32ImageData[10], rgb32ImageData[9], rgb32ImageData[8], rgb32ImageData[11]));
+ QCOMPARE(capture.pixelColor(1, 1), QColor(rgb32ImageData[14], rgb32ImageData[13], rgb32ImageData[12], rgb32ImageData[15]));
+}
+
void tst_QDeclarativeVideoOutput::sourceRect()
{
QQmlComponent component(&m_engine);
diff --git a/tests/auto/integration/qmediaplayerbackend/BLACKLIST b/tests/auto/integration/qmediaplayerbackend/BLACKLIST
index c2833f1f7..e91f47755 100644
--- a/tests/auto/integration/qmediaplayerbackend/BLACKLIST
+++ b/tests/auto/integration/qmediaplayerbackend/BLACKLIST
@@ -5,6 +5,7 @@ windows-7
windows-7sp1
windows-10 msvc-2015
windows-10 msvc-2017
+windows-10 msvc-2019
# Media player plugin not built at the moment on this platform
opensuse-13.1 64bit
diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
index af4e2c275..ec520e901 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -78,8 +78,10 @@ private slots:
void playlistObject();
void surfaceTest_data();
void surfaceTest();
+ void multipleSurfaces();
void metadata();
void playerStateAtEOS();
+ void playFromBuffer();
private:
QMediaContent selectVideoFile(const QStringList& mediaCandidates);
@@ -1389,6 +1391,33 @@ void tst_QMediaPlayerBackend::surfaceTest()
QVERIFY2(surface.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface.m_totalFrames)));
}
+void tst_QMediaPlayerBackend::multipleSurfaces()
+{
+ if (localVideoFile.isNull())
+ QSKIP("No supported video file");
+
+ QList<QVideoFrame::PixelFormat> formats1;
+ formats1 << QVideoFrame::Format_RGB32
+ << QVideoFrame::Format_ARGB32;
+ QList<QVideoFrame::PixelFormat> formats2;
+ formats2 << QVideoFrame::Format_YUV420P
+ << QVideoFrame::Format_RGB32;
+
+ TestVideoSurface surface1(false);
+ surface1.setSupportedFormats(formats1);
+ TestVideoSurface surface2(false);
+ surface2.setSupportedFormats(formats2);
+
+ QMediaPlayer player;
+ player.setVideoOutput(QVector<QAbstractVideoSurface *>() << &surface1 << &surface2);
+ player.setMedia(localVideoFile);
+ player.play();
+ QTRY_VERIFY(player.position() >= 1000);
+ QVERIFY2(surface1.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface1.m_totalFrames)));
+ QVERIFY2(surface2.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface2.m_totalFrames)));
+ QCOMPARE(surface1.m_totalFrames, surface2.m_totalFrames);
+}
+
void tst_QMediaPlayerBackend::metadata()
{
if (localFileWithMetadata.isNull())
@@ -1444,6 +1473,25 @@ void tst_QMediaPlayerBackend::playerStateAtEOS()
QVERIFY(endOfMediaReceived);
}
+void tst_QMediaPlayerBackend::playFromBuffer()
+{
+ if (localVideoFile.isNull())
+ QSKIP("No supported video file");
+
+ TestVideoSurface surface(false);
+ QMediaPlayer player;
+ player.setVideoOutput(&surface);
+ QFile file(localVideoFile.request().url().toLocalFile());
+ if (!file.open(QIODevice::ReadOnly))
+ QSKIP("Could not open file");
+ player.setMedia(localVideoFile, &file);
+ player.play();
+ QTRY_VERIFY(player.position() >= 1000);
+ if (surface.error() == QAbstractVideoSurface::UnsupportedFormatError)
+ QSKIP("None of the pixel formats is supported by the backend");
+ QVERIFY2(surface.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface.m_totalFrames)));
+}
+
TestVideoSurface::TestVideoSurface(bool storeFrames):
m_totalFrames(0),
m_storeFrames(storeFrames)
diff --git a/tests/auto/unit/qabstractvideosurface/tst_qabstractvideosurface.cpp b/tests/auto/unit/qabstractvideosurface/tst_qabstractvideosurface.cpp
index 61299a964..b18dba5f7 100644
--- a/tests/auto/unit/qabstractvideosurface/tst_qabstractvideosurface.cpp
+++ b/tests/auto/unit/qabstractvideosurface/tst_qabstractvideosurface.cpp
@@ -58,7 +58,7 @@ private slots:
void supportedFormatsChanged();
};
-typedef QMap<QAbstractVideoBuffer::HandleType, QVideoFrame::PixelFormat> SupportedFormatMap;
+using SupportedFormatMap = QMultiMap<QAbstractVideoBuffer::HandleType, QVideoFrame::PixelFormat>;
Q_DECLARE_METATYPE(SupportedFormatMap)
@@ -86,7 +86,7 @@ public:
/* fun to generate supportedFormatsChanged signal */
QList<QVideoFrame::PixelFormat> supportedPixelFormatsChange(QList<QVideoFrame::PixelFormat> formats)
{
- supportedFormats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB32);
+ supportedFormats.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB32);
QList<QVideoFrame::PixelFormat> supportedFormats = supportedPixelFormats();
if (supportedFormats.count() != formats.count()) {
emit supportedFormatsChanged();
@@ -189,10 +189,10 @@ void tst_QAbstractVideoSurface::isFormatSupported_data()
QAbstractVideoBuffer::GLTextureHandle)
<< false;
- formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB32);
- formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB24);
- formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YUV444);
- formats.insertMulti(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB32);
+ formats.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB32);
+ formats.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB24);
+ formats.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YUV444);
+ formats.insert(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB32);
QTest::newRow("supported: rgb32")
<< formats
@@ -228,8 +228,8 @@ void tst_QAbstractVideoSurface::isFormatSupported_data()
QAbstractVideoBuffer::GLTextureHandle)
<< false;
- formats.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YV12);
- formats.insertMulti(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB24);
+ formats.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_YV12);
+ formats.insert(QAbstractVideoBuffer::GLTextureHandle, QVideoFrame::Format_RGB24);
QTest::newRow("supported: yv12")
<< formats
@@ -377,7 +377,7 @@ void tst_QAbstractVideoSurface::nativeResolution()
void tst_QAbstractVideoSurface::supportedFormatsChanged()
{
SupportedFormatMap formatMap;
- formatMap.insertMulti(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB24);
+ formatMap.insert(QAbstractVideoBuffer::NoHandle, QVideoFrame::Format_RGB24);
QtTestVideoSurface surface(formatMap);
QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
QList<QVideoFrame::PixelFormat> formats = surface.supportedPixelFormats();
diff --git a/tests/auto/unit/qcamera/tst_qcamera.cpp b/tests/auto/unit/qcamera/tst_qcamera.cpp
index 4b6202173..643b552f9 100644
--- a/tests/auto/unit/qcamera/tst_qcamera.cpp
+++ b/tests/auto/unit/qcamera/tst_qcamera.cpp
@@ -2039,7 +2039,7 @@ void tst_QCamera::testErrorSignal()
QCamera camera;
- QSignalSpy spyError(&camera, SIGNAL(error(QCamera::Error)));
+ QSignalSpy spyError(&camera, SIGNAL(errorOccurred(QCamera::Error)));
/* Set the QCameraControl error and verify if the signal is emitted correctly in QCamera */
service.mockControl->setError(QCamera::CameraError,QString("Camera Error"));
diff --git a/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro b/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro
index f59027bc2..6d8b3c215 100644
--- a/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro
+++ b/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
TARGET = tst_qdeclarativeaudio
-QT += multimedia-private qml testlib
+QT += multimedia-private qml testlib qtmultimediaquicktools-private
HEADERS += \
../../../../src/imports/multimedia/qdeclarativeaudio_p.h \
diff --git a/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp b/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
index 87c72521c..ded188d72 100644
--- a/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
+++ b/tests/auto/unit/qdeclarativeaudio/tst_qdeclarativeaudio.cpp
@@ -40,7 +40,9 @@
#include <qmediaplayercontrol.h>
#include <qmediaservice.h>
#include <private/qmediaserviceprovider_p.h>
+#include <private/qdeclarativevideooutput_p.h>
#include <qmetadatareadercontrol.h>
+#include <QAbstractVideoSurface>
#include <QtGui/qguiapplication.h>
#include <QtQml/qqmlengine.h>
@@ -75,6 +77,7 @@ private slots:
void loops();
void audioRole();
void customAudioRole();
+ void videoOutput();
private:
void enumerator(const QMetaObject *object, const char *name, QMetaEnum *result);
@@ -1201,6 +1204,52 @@ int tst_QDeclarativeAudio::keyToValue(const QMetaEnum &enumeration, const char *
return result;
}
+struct Surface : QAbstractVideoSurface
+{
+ Surface(QObject *parent = nullptr) : QAbstractVideoSurface(parent) { }
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const override
+ {
+ return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32;
+ }
+
+ bool present(const QVideoFrame &) override { return true; }
+};
+
+void tst_QDeclarativeAudio::videoOutput()
+{
+ QtTestMediaPlayerControl playerControl;
+ QtTestMediaServiceProvider provider(&playerControl, 0);
+
+ QDeclarativeAudio audio;
+ QSignalSpy spy(&audio, &QDeclarativeAudio::videoOutputChanged);
+
+ audio.classBegin();
+ audio.componentComplete();
+
+ QVERIFY(audio.videoOutput().isNull());
+
+ QVariant surface;
+ surface.setValue(new Surface(this));
+ audio.setVideoOutput(surface);
+ QCOMPARE(audio.videoOutput(), surface);
+ QCOMPARE(spy.count(), 1);
+
+ QQmlEngine engine;
+ QJSValue jsArray = engine.newArray(5);
+ jsArray.setProperty(0, engine.newQObject(new Surface(this)));
+ jsArray.setProperty(1, engine.newQObject(new Surface(this)));
+ QDeclarativeVideoOutput output;
+ jsArray.setProperty(2, engine.newQObject(&output));
+ jsArray.setProperty(3, 123);
+ jsArray.setProperty(4, QLatin1String("ignore this"));
+
+ QVariant surfaces;
+ surfaces.setValue(jsArray);
+ audio.setVideoOutput(surfaces);
+ QCOMPARE(audio.videoOutput(), surfaces);
+ QCOMPARE(spy.count(), 2);
+}
+
QTEST_MAIN(tst_QDeclarativeAudio)
#include "tst_qdeclarativeaudio.moc"
diff --git a/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp b/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
index f4759bbf7..41805f49a 100644
--- a/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
+++ b/tests/auto/unit/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp
@@ -70,6 +70,7 @@ private slots:
void boundingRect();
void paint();
+ void paintSurface();
};
Q_DECLARE_METATYPE(const uchar *)
@@ -656,6 +657,48 @@ void tst_QGraphicsVideoItem::paint()
QCOMPARE(surface->isReady(), true);
}
+void tst_QGraphicsVideoItem::paintSurface()
+{
+ QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem;
+ QVERIFY(item->videoSurface());
+
+ QGraphicsScene graphicsScene;
+ graphicsScene.addItem(item);
+ QGraphicsView graphicsView(&graphicsScene);
+ graphicsView.show();
+ QVERIFY(item->waitForPaint(1));
+
+ QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>(
+ item->videoSurface());
+ if (!surface)
+ QSKIP("QGraphicsVideoItem is not QPainterVideoSurface based");
+
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+
+ QVERIFY(surface->start(format));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+
+ QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32);
+
+ frame.map(QAbstractVideoBuffer::WriteOnly);
+ memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes());
+ frame.unmap();
+
+ QVERIFY(surface->present(frame));
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), false);
+
+ QVERIFY(item->waitForPaint(1));
+
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+}
QTEST_MAIN(tst_QGraphicsVideoItem)
diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.cpp b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.cpp
index 66ace2045..4167b18ea 100644
--- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.cpp
+++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.cpp
@@ -75,10 +75,10 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const
{
+ QMediaServiceProviderHint::Features result;
if (service == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER))
- return QMediaServiceProviderHint::LowLatencyPlayback;
- else
- return 0;
+ result |= QMediaServiceProviderHint::LowLatencyPlayback;
+ return result;
}
};
diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.cpp b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.cpp
index 92707169c..6a7725fee 100644
--- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.cpp
+++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.cpp
@@ -75,10 +75,10 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const
{
+ QMediaServiceProviderHint::Features result;
if (service == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER))
- return QMediaServiceProviderHint::StreamPlayback;
- else
- return 0;
+ result |= QMediaServiceProviderHint::StreamPlayback;
+ return result;
}
};
diff --git a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
index 7ba631e58..be5c85ab9 100644
--- a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
+++ b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
@@ -35,9 +35,9 @@
#include <qvideosurfaceformat.h>
#if QT_CONFIG(opengl)
-#include <QtOpenGL/qgl.h>
-#include <QtOpenGL/qglframebufferobject.h>
-#include <QtGui/qopenglfunctions.h>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QOpenGLWidget>
#endif
QT_USE_NAMESPACE
@@ -481,8 +481,7 @@ void tst_QPainterVideoSurface::present()
QCOMPARE(surface.isActive(), true);
QCOMPARE(surface.isReady(), false);
- // Not ready.
- QVERIFY(!surface.present(frameA));
+ QVERIFY(surface.present(frameA));
QCOMPARE(frameSpy.count(), 1);
surface.setReady(true);
@@ -560,20 +559,19 @@ void tst_QPainterVideoSurface::presentOpaqueFrame()
void tst_QPainterVideoSurface::shaderType()
{
QPainterVideoSurface surface;
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support OpenGLContext");
QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
QCOMPARE(surface.supportedShaderTypes(), QPainterVideoSurface::NoShaders);
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
QCOMPARE(surface.glContext(), widget.context());
{
@@ -613,12 +611,14 @@ void tst_QPainterVideoSurface::shaderType()
{
QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
QCOMPARE(surface.glContext(), widget.context());
QCOMPARE(spy.count(), 0);
}
- surface.setGLContext(0);
+ widget.doneCurrent();
+ surface.updateGLContext();
QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
QCOMPARE(surface.supportedShaderTypes(), QPainterVideoSurface::NoShaders);
@@ -657,19 +657,18 @@ void tst_QPainterVideoSurface::shaderTypeStarted()
{
QFETCH(QPainterVideoSurface::ShaderType, shaderType);
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support OpenGLContext");
QPainterVideoSurface surface;
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
if (!(surface.supportedShaderTypes() & shaderType))
QSKIP("Shader type unsupported on this platform");
@@ -713,7 +712,8 @@ void tst_QPainterVideoSurface::shaderTypeStarted()
QCOMPARE(surface.isActive(), true);
QCOMPARE(spy.count(), 0);
- surface.setGLContext(0);
+ widget.doneCurrent();
+ surface.updateGLContext();
QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
QCOMPARE(surface.isActive(), false);
QCOMPARE(spy.count(), 1);
@@ -905,18 +905,17 @@ void tst_QPainterVideoSurface::shaderSupportedFormat()
QFETCH(bool, supportedPixelFormat);
QFETCH(bool, supportedFormat);
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support GLContext");
QPainterVideoSurface surface;
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
if (!(surface.supportedShaderTypes() & shaderType))
@@ -1027,18 +1026,17 @@ void tst_QPainterVideoSurface::shaderPresent()
QFETCH(int, bytesB);
QFETCH(int, bytesPerLineB);
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support GLContext");
QPainterVideoSurface surface;
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
if (!(surface.supportedShaderTypes() & shaderType))
QSKIP("Shader type unsupported on this platform");
@@ -1093,8 +1091,9 @@ void tst_QPainterVideoSurface::shaderPresent()
QCOMPARE(surface.isActive(), true);
QCOMPARE(surface.isReady(), false);
- // Not ready.
- QVERIFY(!surface.present(frameA));
+ // If present() fails for any other reason the surface should immediately enter the stopped state
+ // and an error() value will be set.
+ QVERIFY(surface.present(frameA));
QCOMPARE(frameSpy.count(), 1);
surface.setReady(true);
@@ -1163,18 +1162,17 @@ void tst_QPainterVideoSurface::shaderPresentOpaqueFrame()
{
QFETCH(QPainterVideoSurface::ShaderType, shaderType);
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support GLContext");
QPainterVideoSurface surface;
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
if (!(surface.supportedShaderTypes() & shaderType))
QSKIP("Shader type unsupported on this platform");
@@ -1217,18 +1215,17 @@ void tst_QPainterVideoSurface::shaderPresentGLFrame()
{
QFETCH(QPainterVideoSurface::ShaderType, shaderType);
- QGLWidget widget;
- if (!widget.context()
- || !widget.context()->isValid()) {
- QSKIP("Platform does not support GLContext");
- }
-
+ QOpenGLWidget widget;
widget.show();
+
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- widget.makeCurrent();
+
+ if (!widget.context() || !widget.context()->isValid())
+ QSKIP("Platform does not support GLContext");
QPainterVideoSurface surface;
- surface.setGLContext(const_cast<QGLContext *>(widget.context()));
+ widget.makeCurrent();
+ surface.updateGLContext();
if (!(surface.supportedShaderTypes() & shaderType))
QSKIP("Shader type unsupported on this platform");
diff --git a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
index 6be039108..943051435 100644
--- a/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
+++ b/tests/auto/unit/qvideoframe/tst_qvideoframe.cpp
@@ -33,6 +33,7 @@
#include <qvideoframe.h>
#include <QtGui/QImage>
#include <QtCore/QPointer>
+#include <QtMultimedia/private/qtmultimedia-config_p.h>
// Adds an enum, and the stringized version
#define ADD_ENUM_TEST(x) \
@@ -85,6 +86,9 @@ private slots:
void isMapped();
void isReadable();
void isWritable();
+
+ void image_data();
+ void image();
};
Q_DECLARE_METATYPE(QImage::Format)
@@ -1128,6 +1132,173 @@ void tst_QVideoFrame::isWritable()
frame.unmap();
}
+void tst_QVideoFrame::image_data()
+{
+ QTest::addColumn<QSize>("size");
+ QTest::addColumn<QVideoFrame::PixelFormat>("pixelFormat");
+ QTest::addColumn<int>("bytes");
+ QTest::addColumn<int>("bytesPerLine");
+ QTest::addColumn<QImage::Format>("imageFormat");
+
+ QTest::newRow("64x64 ARGB32")
+ << QSize(64, 64)
+ << QVideoFrame::Format_ARGB32
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 ARGB32_Premultiplied")
+ << QSize(64, 64)
+ << QVideoFrame::Format_ARGB32_Premultiplied
+ << 16384
+ << 256
+ << QImage::Format_ARGB32_Premultiplied;
+
+ QTest::newRow("64x64 RGB32")
+ << QSize(64, 64)
+ << QVideoFrame::Format_RGB32
+ << 16384
+ << 256
+ << QImage::Format_RGB32;
+
+ QTest::newRow("64x64 RGB24")
+ << QSize(64, 64)
+ << QVideoFrame::Format_RGB24
+ << 16384
+ << 192
+ << QImage::Format_RGB888;
+
+ QTest::newRow("64x64 RGB565")
+ << QSize(64, 64)
+ << QVideoFrame::Format_RGB565
+ << 16384
+ << 128
+ << QImage::Format_RGB16;
+
+ QTest::newRow("64x64 RGB555")
+ << QSize(64, 64)
+ << QVideoFrame::Format_RGB555
+ << 16384
+ << 128
+ << QImage::Format_RGB555;
+
+ QTest::newRow("64x64 BGRA32")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGRA32
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 BGRA32_Premultiplied")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGRA32_Premultiplied
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 BGR32")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGR32
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 BGR24")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGR24
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 BGR565")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGR565
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 BGR555")
+ << QSize(64, 64)
+ << QVideoFrame::Format_BGR555
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+#if !QT_CONFIG(directshow)
+ QTest::newRow("64x64 AYUV444")
+ << QSize(64, 64)
+ << QVideoFrame::Format_AYUV444
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 YUV444")
+ << QSize(64, 64)
+ << QVideoFrame::Format_YUV444
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 YUV420P")
+ << QSize(64, 64)
+ << QVideoFrame::Format_YUV420P
+ << 13288
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 YV12")
+ << QSize(64, 64)
+ << QVideoFrame::Format_YV12
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 UYVY")
+ << QSize(64, 64)
+ << QVideoFrame::Format_UYVY
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 YUYV")
+ << QSize(64, 64)
+ << QVideoFrame::Format_YUYV
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 NV12")
+ << QSize(64, 64)
+ << QVideoFrame::Format_NV12
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+
+ QTest::newRow("64x64 NV21")
+ << QSize(64, 64)
+ << QVideoFrame::Format_NV21
+ << 16384
+ << 256
+ << QImage::Format_ARGB32;
+#endif
+}
+
+void tst_QVideoFrame::image()
+{
+ QFETCH(QSize, size);
+ QFETCH(QVideoFrame::PixelFormat, pixelFormat);
+ QFETCH(int, bytes);
+ QFETCH(int, bytesPerLine);
+ QFETCH(QImage::Format, imageFormat);
+
+ QVideoFrame frame(bytes, size, bytesPerLine, pixelFormat);
+ QImage img = frame.image();
+
+ QVERIFY(!img.isNull());
+ QCOMPARE(img.format(), imageFormat);
+ QCOMPARE(img.size(), size);
+ QCOMPARE(img.bytesPerLine(), bytesPerLine);
+}
+
QTEST_MAIN(tst_QVideoFrame)
#include "tst_qvideoframe.moc"
diff --git a/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp b/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
index 3baa72281..bcc4acb3a 100644
--- a/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
+++ b/tests/auto/unit/qvideowidget/tst_qvideowidget.cpp
@@ -100,6 +100,7 @@ private slots:
void saturationRendererControl();
void paintRendererControl();
+ void paintSurface();
private:
void sizeHint_data();
@@ -1609,6 +1610,34 @@ void tst_QVideoWidget::paintRendererControl()
QCOMPARE(surface->isReady(), true);
}
+void tst_QVideoWidget::paintSurface()
+{
+ QtTestVideoWidget widget;
+ widget.resize(640,480);
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QVERIFY(widget.videoSurface());
+ auto surface = qobject_cast<QPainterVideoSurface *>(
+ widget.videoSurface());
+ QVERIFY(surface);
+
+ QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32);
+ QVERIFY(surface->start(format));
+ QCOMPARE(surface->isActive(), true);
+
+ QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32);
+ frame.map(QAbstractVideoBuffer::WriteOnly);
+ memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes());
+ frame.unmap();
+
+ QVERIFY(surface->present(frame));
+ QCOMPARE(surface->isReady(), false);
+ QTRY_COMPARE(surface->isReady(), true);
+ QCOMPARE(surface->isActive(), true);
+ QCOMPARE(surface->isReady(), true);
+}
+
QTEST_MAIN(tst_QVideoWidget)
#include "tst_qvideowidget.moc"