summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/multimedia/spectrum/app/engine.cpp6
-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.cpp12
-rw-r--r--src/gsttools/qgstreamerbufferprobe.cpp4
-rw-r--r--src/gsttools/qgstreamerbushelper.cpp10
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp108
-rw-r--r--src/gsttools/qgstreamervideooverlay.cpp46
-rw-r--r--src/gsttools/qgstutils.cpp58
-rw-r--r--src/gsttools/qgstvideorenderersink.cpp26
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp18
-rw-r--r--src/imports/multimedia/multimedia.cpp5
-rw-r--r--src/multimedia/doc/snippets/multimedia-snippets/video.cpp23
-rw-r--r--src/multimedia/playback/qmediaplayer.cpp21
-rw-r--r--src/multimedia/playback/qmediaplayer.h1
-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.cpp94
-rw-r--r--src/multimedia/video/qvideosurfaces_p.h (renamed from src/multimedia/video/qvideoframe_p.h)30
-rw-r--r--src/multimedia/video/video.pri7
-rw-r--r--src/multimediawidgets/qgraphicsvideoitem.cpp16
-rw-r--r--src/multimediawidgets/qgraphicsvideoitem.h2
-rw-r--r--src/multimediawidgets/qpaintervideosurface.cpp19
-rw-r--r--src/multimediawidgets/qvideowidget.cpp62
-rw-r--r--src/multimediawidgets/qvideowidget.h3
-rw-r--r--src/multimediawidgets/qvideowidget_p.h47
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.cpp3
-rw-r--r--src/plugins/avfoundation/camera/avfimagecapturecontrol.mm3
-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.cpp23
-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.cpp5
-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.cpp28
-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.cpp8
-rw-r--r--tests/auto/unit/qvideoframe/tst_qvideoframe.cpp171
-rw-r--r--tests/auto/unit/qvideowidget/tst_qvideowidget.cpp29
49 files changed, 816 insertions, 265 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 09a75f0b9..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.1
+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/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..36b36dda4 100644
--- a/src/gsttools/qgstreameraudioinputselector.cpp
+++ b/src/gsttools/qgstreameraudioinputselector.cpp
@@ -124,23 +124,23 @@ 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)
+ if (name != nullptr)
free(name);
- if (descr != NULL)
+ if (descr != nullptr)
free(descr);
- if (io != NULL)
+ if (io != nullptr)
free(io);
n++;
}
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..1d16df5b7 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();
@@ -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..f998c4309 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);
@@ -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/multimedia.cpp b/src/imports/multimedia/multimedia.cpp
index 8aed83d33..6106bb45d 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,10 @@ public:
// 5.13 types
qmlRegisterType<QDeclarativeVideoOutput, 13>(uri, 5, 13, "VideoOutput");
+ // 5.15 types
+ 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/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 48db0335e..9b51bcddf 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"
@@ -555,7 +556,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;
@@ -1168,6 +1169,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(new QVideoSurfaces(surfaces, this));
+}
+
/*! \reimp */
QMultimedia::AvailabilityStatus QMediaPlayer::availability() const
{
diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h
index 5d9a393e1..7ebed84da 100644
--- a/src/multimedia/playback/qmediaplayer.h
+++ b/src/multimedia/playback/qmediaplayer.h
@@ -131,6 +131,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;
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..459a6675a
--- /dev/null
+++ b/src/multimedia/video/qvideosurfaces.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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)
+{
+}
+
+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/qvideoframe_p.h b/src/multimedia/video/qvideosurfaces_p.h
index d7b9dd348..67831e74e 100644
--- a/src/multimedia/video/qvideoframe_p.h
+++ b/src/multimedia/video/qvideosurfaces_p.h
@@ -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,10 +37,8 @@
**
****************************************************************************/
-#ifndef QVIDEOFRAME_P_H
-#define QVIDEOFRAME_P_H
-
-#include <QtMultimedia/qvideoframe.h>
+#ifndef QVIDEOSURFACES_P_H
+#define QVIDEOSURFACES_P_H
//
// W A R N I N G
@@ -53,11 +51,27 @@
// We mean it.
//
+#include <QAbstractVideoSurface>
+#include <QVector>
+
QT_BEGIN_NAMESPACE
-Q_MULTIMEDIA_EXPORT QImage qt_imageFromVideoFrame(const QVideoFrame &frame);
+class QVideoSurfaces : public QAbstractVideoSurface
+{
+public:
+ QVideoSurfaces(const QVector<QAbstractVideoSurface *> &surfaces, QObject *parent = nullptr);
+ ~QVideoSurfaces();
-QT_END_NAMESPACE
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override;
+ bool start(const QVideoSurfaceFormat &format) override;
+ void stop() override;
+ bool present(const QVideoFrame &frame) override;
-#endif // QVIDEOFRAME_P_H
+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..fae1f9048 100644
--- a/src/multimediawidgets/qgraphicsvideoitem.cpp
+++ b/src/multimediawidgets/qgraphicsvideoitem.cpp
@@ -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)
diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h
index 5aa3bd75c..de73458fd 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)
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..1c8e2dd63 100644
--- a/src/multimediawidgets/qpaintervideosurface.cpp
+++ b/src/multimediawidgets/qpaintervideosurface.cpp
@@ -1473,29 +1473,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;
}
/*!
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp
index a7d3665f8..723a9bbb3 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)
@@ -469,7 +477,7 @@ void QVideoWidgetPrivate::clearService()
delete rendererBackend;
rendererBackend = 0;
- } else {
+ } else if (windowBackend) {
windowBackend->releaseControl();
delete windowBackend;
@@ -515,18 +523,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 +616,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 +626,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 +701,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..c5abe2ce3 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)
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..1db91f3f9 100644
--- a/src/multimediawidgets/qvideowidget_p.h
+++ b/src/multimediawidgets/qvideowidget_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/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/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..128d0a616 100644
--- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
@@ -138,6 +138,7 @@ QDeclarativeVideoOutput::QDeclarativeVideoOutput(QQuickItem *parent) :
{
initResource();
setFlag(ItemHasContents, true);
+ m_backend.reset(new QDeclarativeVideoRendererBackend(this));
}
QDeclarativeVideoOutput::~QDeclarativeVideoOutput()
@@ -148,6 +149,22 @@ 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 setSource
+*/
+
+QAbstractVideoSurface *QDeclarativeVideoOutput::videoSurface() const
+{
+ return m_backend->videoSurface();
+}
+
+/*!
\qmlproperty variant QtMultimedia::VideoOutput::source
This property holds the source item providing the video frames like MediaPlayer or Camera.
@@ -251,7 +268,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 +311,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..9e826d0ff 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 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..27fc014aa 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
@@ -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());
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 9cd3b7fa9..f1be070e8 100644
--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
@@ -78,6 +78,7 @@ private slots:
void playlistObject();
void surfaceTest_data();
void surfaceTest();
+ void multipleSurfaces();
void metadata();
void playerStateAtEOS();
@@ -1393,6 +1394,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())
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..6aaeab855 100644
--- a/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
+++ b/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp
@@ -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);
@@ -1093,8 +1092,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);
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"