From 5f11c33fd54bfdc51e918d8976ee0405e8835481 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 13 Jul 2015 15:14:48 +0200 Subject: [PATCH 01/10] WindowsAudio: Fix compiler warnings by g++/MinGW. Replace NULL by 0 for parameters of type DWORD_PTR. qwindowsaudiodeviceinfo.cpp: In member function 'bool QWindowsAudioDeviceInfo::testSettings(const QAudioFormat&) const': qwindowsaudiodeviceinfo.cpp:220:50: warning: passing NULL to non-pointer argument 4 of 'MMRESULT waveOutOpen(LPHWAVEOUT, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD)' [-Wconversion-null] WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); ^ qwindowsaudiodeviceinfo.cpp:220:50: warning: passing NULL to non-pointer argument 5 of 'MMRESULT waveOutOpen(LPHWAVEOUT, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD)' [-Wconversion-null] qwindowsaudiodeviceinfo.cpp:223:50: warning: passing NULL to non-pointer argument 4 of 'MMRESULT waveInOpen(LPHWAVEIN, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD)' [-Wconversion-null] WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); ^ qwindowsaudiodeviceinfo.cpp:223:50: warning: passing NULL to non-pointer argument 5 of 'MMRESULT waveInOpen(LPHWAVEIN, UINT, LPCWAVEFORMATEX, DWORD_PTR, DWORD_PTR, DWORD)' [-Wconversion-null]# ==[ Please wrap at 72 characters ]===================================| Change-Id: Ie8f65e0e1f4f1274a1b634f3701ae0103e716d97 Reviewed-by: Yoann Lopes --- src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp index 801f792e..039bafea 100644 --- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp @@ -216,10 +216,10 @@ bool QWindowsAudioDeviceInfo::testSettings(const QAudioFormat& format) const if (qt_convertFormat(format, &wfx)) { // query only, do not open device if (mode == QAudio::AudioOutput) { - return (waveOutOpen(NULL, UINT_PTR(devId), &wfx.Format, NULL, NULL, + return (waveOutOpen(NULL, UINT_PTR(devId), &wfx.Format, 0, 0, WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); } else { // AudioInput - return (waveInOpen(NULL, UINT_PTR(devId), &wfx.Format, NULL, NULL, + return (waveInOpen(NULL, UINT_PTR(devId), &wfx.Format, 0, 0, WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR); } } From bcdac5539d1cb0ed04ff568a236aeb1c105156ce Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 13 Jul 2015 09:45:25 +0200 Subject: [PATCH 02/10] GStreamer: fix supported values returned by CameraBinImageProcessing. Change-Id: I5a4db9c055495714943421742dd237b6abf7daee Reviewed-by: Andrew den Exter --- .../camerabin/camerabinimageprocessing.cpp | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp index 74f34655..633662c7 100644 --- a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp @@ -48,13 +48,15 @@ CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session) m_whiteBalanceMode(QCameraImageProcessing::WhiteBalanceAuto) { #ifdef HAVE_GST_PHOTOGRAPHY - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten; - m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent; - unlockWhiteBalance(); + if (m_session->photography()) { + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto; + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight; + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy; + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset; + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten; + m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent; + unlockWhiteBalance(); + } #if GST_CHECK_VERSION(1, 0, 0) m_filterMap.insert(QCameraImageProcessing::ColorFilterNone, GST_PHOTOGRAPHY_COLOR_TONE_MODE_NORMAL); @@ -188,10 +190,19 @@ bool CameraBinImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessin bool CameraBinImageProcessing::isParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const { - return parameter == QCameraImageProcessingControl::Contrast +#ifdef HAVE_GST_PHOTOGRAPHY + if (parameter == QCameraImageProcessingControl::WhiteBalancePreset + || parameter == QCameraImageProcessingControl::ColorFilter) + return m_session->photography(); +#endif + + if (parameter == QCameraImageProcessingControl::Contrast || parameter == QCameraImageProcessingControl::Brightness - || parameter == QCameraImageProcessingControl::Saturation - || parameter == QCameraImageProcessingControl::WhiteBalancePreset; + || parameter == QCameraImageProcessingControl::Saturation) { + return GST_IS_COLOR_BALANCE(m_session->cameraBin()); + } + + return false; } bool CameraBinImageProcessing::isParameterValueSupported(QCameraImageProcessingControl::ProcessingParameter parameter, const QVariant &value) const @@ -200,7 +211,7 @@ bool CameraBinImageProcessing::isParameterValueSupported(QCameraImageProcessingC case ContrastAdjustment: case BrightnessAdjustment: case SaturationAdjustment: - return qAbs(value.toReal()) <= 1.0; + return GST_IS_COLOR_BALANCE(m_session->cameraBin()) && qAbs(value.toReal()) <= 1.0; case WhiteBalancePreset: return isWhiteBalanceModeSupported(value.value()); case ColorFilter: { From 9ae70447d507dc44f0b3402340a23946d1863056 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 15 Jul 2015 15:14:52 +0200 Subject: [PATCH 03/10] Doc: replace Mac OS X with OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-40759 Change-Id: I11b3aa74d35064371cbbbeba660114e086b16aea Reviewed-by: Martin Smith Reviewed-by: Topi Reiniƶ --- src/multimedia/audio/qaudiosystemplugin.cpp | 2 +- src/multimedia/doc/src/qtmultimedia-examples.qdoc | 2 +- src/multimedia/video/qabstractvideobuffer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/multimedia/audio/qaudiosystemplugin.cpp b/src/multimedia/audio/qaudiosystemplugin.cpp index 895ed0cf..de719fce 100644 --- a/src/multimedia/audio/qaudiosystemplugin.cpp +++ b/src/multimedia/audio/qaudiosystemplugin.cpp @@ -66,7 +66,7 @@ QAudioSystemFactoryInterface::~QAudioSystemFactoryInterface() \sa QAbstractAudioDeviceInfo, QAbstractAudioOutput, QAbstractAudioInput - Qt supports win32, linux(alsa) and Mac OS X standard (builtin to the + Qt supports win32, linux(alsa) and OS X standard (builtin to the QtMultimedia library at compile time). You can support other backends other than these predefined ones by diff --git a/src/multimedia/doc/src/qtmultimedia-examples.qdoc b/src/multimedia/doc/src/qtmultimedia-examples.qdoc index f809edf2..582efc5e 100644 --- a/src/multimedia/doc/src/qtmultimedia-examples.qdoc +++ b/src/multimedia/doc/src/qtmultimedia-examples.qdoc @@ -32,6 +32,6 @@ \brief Demonstrates the multimedia functionality provided by Qt. The \l{Qt Multimedia} module provides low-level audio support on Linux, - Windows and Mac OS X. It also provides audio plugin API to allow developers + Windows and OS X. It also provides audio plugin API to allow developers implement their own audio support for custom devices and platforms. */ diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp index ff29bd0b..6dca8dad 100644 --- a/src/multimedia/video/qabstractvideobuffer.cpp +++ b/src/multimedia/video/qabstractvideobuffer.cpp @@ -92,7 +92,7 @@ int QAbstractVideoBufferPrivate::map( \value NoHandle The buffer has no handle, its data can only be accessed by mapping the buffer. \value GLTextureHandle The handle of the buffer is an OpenGL texture ID. \value XvShmImageHandle The handle contains pointer to shared memory XVideo image. - \value CoreImageHandle The handle contains pointer to Mac OS X CIImage. + \value CoreImageHandle The handle contains pointer to OS X CIImage. \value QPixmapHandle The handle of the buffer is a QPixmap. \value EGLImageHandle The handle of the buffer is an EGLImageKHR. \value UserHandle Start value for user defined handle types. From f25034afaf67c32057797ae790505e57a92deffc Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 17 Jul 2015 11:37:02 +0200 Subject: [PATCH 04/10] Fix video nodes material comparison. Don't consider a material equal to another when their texture IDs are not available yet. Change-Id: Id4127d71abb2db33950a206dc722b24ab626e960 Task-number: QTBUG-47205 Reviewed-by: Gunnar Sletta --- src/qtmultimediaquicktools/qsgvideonode_rgb.cpp | 4 ++++ src/qtmultimediaquicktools/qsgvideonode_texture.cpp | 4 ++++ src/qtmultimediaquicktools/qsgvideonode_yuv.cpp | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp index 0f682d1e..5093acb5 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp @@ -145,6 +145,10 @@ public: virtual int compare(const QSGMaterial *other) const { const QSGVideoMaterial_RGB *m = static_cast(other); + + if (!m_textureId) + return 1; + return m_textureId - m->m_textureId; } diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index fd8d8719..500c1c62 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -138,6 +138,10 @@ public: virtual int compare(const QSGMaterial *other) const { const QSGVideoMaterial_Texture *m = static_cast(other); + + if (!m_textureId) + return 1; + int diff = m_textureId - m->m_textureId; if (diff) return diff; diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index c920ba3b..af1e98cd 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -171,6 +171,9 @@ public: virtual int compare(const QSGMaterial *other) const { const QSGVideoMaterial_YUV *m = static_cast(other); + if (!m_textureIds[0]) + return 1; + int d = m_textureIds[0] - m->m_textureIds[0]; if (d) return d; From 94eb599b6995f8b8e6a132d553620f891e138129 Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Wed, 22 Jul 2015 18:34:02 +0300 Subject: [PATCH 05/10] winrt: Fix crash during certain video operations The abstract video buffer pointer was being reused and (improperly) deleted when its reference count went to zero. As QVideoFrame utilizes an explicitly shared pointer which also tracks the video buffer, simply reuse the QVideoFrame instance instead. Task-number: QTBUG-47373 Change-Id: Idadae205cb520a0a1d752aa20256c0567b3be699 Reviewed-by: Andrew Knight --- .../qwinrtabstractvideorenderercontrol.cpp | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp index aa0f721b..4a225e9c 100644 --- a/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp +++ b/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp @@ -125,21 +125,13 @@ Q_GLOBAL_STATIC(QWinRTVideoRendererControlGlobal, g) class QWinRTVideoBuffer : public QAbstractVideoBuffer, public QOpenGLTexture { public: - QWinRTVideoBuffer() + QWinRTVideoBuffer(const QSize &size, TextureFormat format) : QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle) , QOpenGLTexture(QOpenGLTexture::Target2D) { - } - - void addRef() - { - refCount.ref(); - } - - void release() Q_DECL_OVERRIDE - { - if (!refCount.deref()) - delete this; + setSize(size.width(), size.height()); + setFormat(format); + create(); } MapMode mapMode() const Q_DECL_OVERRIDE @@ -163,9 +155,6 @@ public: { return QVariant::fromValue(textureId()); } - -private: - QAtomicInt refCount; }; enum DirtyState { @@ -189,7 +178,7 @@ public: EGLConfig eglConfig; EGLSurface eglSurface; - QWinRTVideoBuffer *videoBuffer; + QVideoFrame presentFrame; QThread renderThread; bool active; @@ -224,8 +213,6 @@ QWinRTAbstractVideoRendererControl::QWinRTAbstractVideoRendererControl(const QSi d->eglSurface = EGL_NO_SURFACE; d->active = false; - d->videoBuffer = new QWinRTVideoBuffer; - connect(&d->renderThread, &QThread::started, this, &QWinRTAbstractVideoRendererControl::syncAndRender, Qt::DirectConnection); @@ -390,23 +377,19 @@ void QWinRTAbstractVideoRendererControl::present() return; } - d->videoBuffer->setFormat(QOpenGLTexture::RGBAFormat); - d->videoBuffer->setSize(d->format.frameWidth(), d->format.frameHeight()); - if (!d->videoBuffer->isCreated()) - d->videoBuffer->create(); + QWinRTVideoBuffer *videoBuffer = new QWinRTVideoBuffer(d->format.frameSize(), QOpenGLTexture::RGBAFormat); + d->presentFrame = QVideoFrame(videoBuffer, d->format.frameSize(), d->format.pixelFormat()); // bind the pbuffer surface to the texture - d->videoBuffer->bind(); + videoBuffer->bind(); eglBindTexImage(d->eglDisplay, d->eglSurface, EGL_BACK_BUFFER); - static_cast(d->videoBuffer)->release(); + static_cast(videoBuffer)->release(); d->dirtyState = NotDirty; } // Present the frame - d->videoBuffer->addRef(); - QVideoFrame frame(d->videoBuffer, d->format.frameSize(), d->format.pixelFormat()); - d->surface->present(frame); + d->surface->present(d->presentFrame); } QT_END_NAMESPACE From b6dd9558a708e6961426db23863039ee1015e34d Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 7 Jul 2015 15:28:36 +0200 Subject: [PATCH 06/10] GStreamer: fix possible integer overflow in comparison. Change-Id: I6cf4349f89320f72cce4d04cdf909476e583d11f Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinsession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index ed7e7d41..10217c1c 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -1304,7 +1304,7 @@ static QPair valueRange(const GValue *value, bool *continuous) static bool resolutionLessThan(const QSize &r1, const QSize &r2) { - return r1.width()*r1.height() < r2.width()*r2.height(); + return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height(); } From 6b19a24b581c9c6086989532a909169afc62028c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 7 Jul 2015 15:29:52 +0200 Subject: [PATCH 07/10] GStreamer: use QMediaStorageLocation to generate capture file names. Change-Id: I2111eb8e28f60ca6305a48a8ee9299bc14ab0df9 Reviewed-by: Christian Stromme --- .../gstreamer/camerabin/camerabinsession.cpp | 81 +++---------------- .../gstreamer/camerabin/camerabinsession.h | 5 +- 2 files changed, 15 insertions(+), 71 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 10217c1c..da317740 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -542,9 +542,10 @@ GstElement *CameraBinSession::buildCameraSource() void CameraBinSession::captureImage(int requestId, const QString &fileName) { - QString actualFileName = fileName; - if (actualFileName.isEmpty()) - actualFileName = generateFileName("img_", defaultDir(QCamera::CaptureStillImage), "jpg"); + const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, + QMediaStorageLocation::Pictures, + QLatin1String("IMG_"), + QLatin1String("jpg")); m_requestId = requestId; @@ -592,60 +593,6 @@ bool CameraBinSession::setOutputLocation(const QUrl& sink) return true; } -QDir CameraBinSession::defaultDir(QCamera::CaptureModes mode) const -{ - QStringList dirCandidates; - -#if defined(Q_WS_MAEMO_6) - dirCandidates << QLatin1String("/home/user/MyDocs/DCIM"); - dirCandidates << QLatin1String("/home/user/MyDocs/"); -#endif - - if (mode == QCamera::CaptureVideo) { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - dirCandidates << QDir::home().filePath("Documents/Video"); - dirCandidates << QDir::home().filePath("Documents/Videos"); - } else { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - dirCandidates << QDir::home().filePath("Documents/Photo"); - dirCandidates << QDir::home().filePath("Documents/Photos"); - dirCandidates << QDir::home().filePath("Documents/photo"); - dirCandidates << QDir::home().filePath("Documents/photos"); - dirCandidates << QDir::home().filePath("Documents/Images"); - } - - dirCandidates << QDir::home().filePath("Documents"); - dirCandidates << QDir::home().filePath("My Documents"); - dirCandidates << QDir::homePath(); - dirCandidates << QDir::currentPath(); - dirCandidates << QDir::tempPath(); - - foreach (const QString &path, dirCandidates) { - if (QFileInfo(path).isWritable()) - return QDir(path); - } - - return QDir(); -} - -QString CameraBinSession::generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const -{ - int lastClip = 0; - foreach(QString fileName, dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(ext))) { - int imgNumber = fileName.midRef(prefix.length(), fileName.size()-prefix.length()-ext.length()-1).toInt(); - lastClip = qMax(lastClip, imgNumber); - } - - QString name = QString("%1%2.%3").arg(prefix) - .arg(lastClip+1, - 4, //fieldWidth - 10, - QLatin1Char('0')) - .arg(ext); - - return dir.absoluteFilePath(name); -} - void CameraBinSession::setDevice(const QString &device) { if (m_inputDevice != device) { @@ -1122,18 +1069,16 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message) void CameraBinSession::recordVideo() { - m_recordingActive = true; - m_actualSink = m_sink; - if (m_actualSink.isEmpty()) { - QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->actualContainerFormat()); - m_actualSink = QUrl::fromLocalFile(generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext)); - } else { - // Output location was rejected in setOutputlocation() if not a local file - m_actualSink = QUrl::fromLocalFile(QDir::currentPath()).resolved(m_actualSink); - } + const QString actualFileName = m_mediaStorageLocation.generateFileName(m_sink.isLocalFile() ? m_sink.toLocalFile() + : m_sink.toString(), + QMediaStorageLocation::Movies, + QLatin1String("clip_"), + m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->actualContainerFormat())); - QString fileName = m_actualSink.toLocalFile(); - g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, QFile::encodeName(fileName).constData(), NULL); + m_recordingActive = true; + m_actualSink = QUrl::fromLocalFile(actualFileName); + + g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, QFile::encodeName(actualFileName).constData(), NULL); g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL); } diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h index 71590a7d..553c2a1a 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.h +++ b/src/plugins/gstreamer/camerabin/camerabinsession.h @@ -46,6 +46,7 @@ #include #include +#include #include "qcamera.h" QT_BEGIN_NAMESPACE @@ -102,9 +103,6 @@ public: QUrl outputLocation() const; bool setOutputLocation(const QUrl& sink); - QDir defaultDir(QCamera::CaptureModes mode) const; - QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const; - GstElement *buildCameraSource(); GstElementFactory *sourceFactory() const { return m_sourceFactory; } @@ -209,6 +207,7 @@ private: QString m_inputDevice; bool m_muted; bool m_busy; + QMediaStorageLocation m_mediaStorageLocation; QCamera::CaptureModes m_captureMode; QMap m_metaData; From b048f262814b49b147b043bf9bb6200756067981 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Jul 2015 16:36:12 -0700 Subject: [PATCH 08/10] Don't list avfcamerainfocontrol header and sources twice This produces Makefile warnings Makefile.Debug:351: warning: overriding commands for target `.obj/debug/avfcamerainfocontrol.o' Makefile.Debug:337: warning: ignoring old commands for target `.obj/debug/avfcamerainfocontrol.o' Makefile.Debug:514: warning: overriding commands for target `.moc/debug/moc_avfcamerainfocontrol.cpp' Makefile.Debug:506: warning: ignoring old commands for target `.moc/debug/moc_avfcamerainfocontrol.cpp' Makefile.Debug:351: warning: overriding commands for target `.obj/debug/avfcamerainfocontrol.o' Makefile.Debug:337: warning: ignoring old commands for target `.obj/debug/avfcamerainfocontrol.o' Makefile.Debug:514: warning: overriding commands for target `.moc/debug/moc_avfcamerainfocontrol.cpp' Makefile.Debug:506: warning: ignoring old commands for target `.moc/debug/moc_avfcamerainfocontrol.cpp' Change-Id: I2ec77cb92b4d218e5b07d895fdb96497061b527b Reviewed-by: Yoann Lopes --- src/plugins/avfoundation/camera/camera.pro | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro index 62afdcd8..a82d88de 100644 --- a/src/plugins/avfoundation/camera/camera.pro +++ b/src/plugins/avfoundation/camera/camera.pro @@ -33,7 +33,6 @@ HEADERS += \ avfaudioinputselectorcontrol.h \ avfcamerainfocontrol.h \ avfmediavideoprobecontrol.h \ - avfcamerainfocontrol.h \ avfcamerarenderercontrol.h \ avfcameradevicecontrol.h \ avfcamerafocuscontrol.h \ @@ -54,7 +53,6 @@ OBJECTIVE_SOURCES += \ avfaudioinputselectorcontrol.mm \ avfcamerainfocontrol.mm \ avfmediavideoprobecontrol.mm \ - avfcamerainfocontrol.mm \ avfcameradevicecontrol.mm \ avfcamerarenderercontrol.mm \ avfcamerafocuscontrol.mm \ From bc9cfcd08acd439c85fee5ffa1a768f8aebeff6f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Jul 2015 16:26:25 -0700 Subject: [PATCH 09/10] Fix warnings about unused private fields avfaudioinputselectorcontrol.h:68:23: warning: private field 'm_service' is not used [-Wunused-private-field] Change-Id: I5722a2d1bf592862af3a4d36554419a653662892 Reviewed-by: Yoann Lopes --- src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h | 2 -- .../avfoundation/camera/avfaudioinputselectorcontrol.mm | 2 +- src/plugins/avfoundation/camera/avfcameracontrol.h | 1 - src/plugins/avfoundation/camera/avfcameracontrol.mm | 2 +- src/plugins/avfoundation/camera/avfcamerametadatacontrol.h | 1 - src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm | 3 ++- src/plugins/avfoundation/camera/avfimagecapturecontrol.h | 1 - src/plugins/avfoundation/camera/avfimagecapturecontrol.mm | 2 +- 8 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h index 8ad89bcc..5d629f66 100644 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h +++ b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h @@ -65,8 +65,6 @@ public: AVCaptureDevice *createCaptureDevice(); private: - AVFCameraService *m_service; - QString m_activeInput; bool m_dirty; QString m_defaultDevice; diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm index d0d0c820..d06ae199 100644 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm +++ b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm @@ -41,9 +41,9 @@ QT_USE_NAMESPACE AVFAudioInputSelectorControl::AVFAudioInputSelectorControl(AVFCameraService *service, QObject *parent) : QAudioInputSelectorControl(parent) - , m_service(service) , m_dirty(true) { + Q_UNUSED(service); NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]; for (AVCaptureDevice *device in videoDevices) { QString deviceId = QString::fromUtf8([[device uniqueID] UTF8String]); diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.h b/src/plugins/avfoundation/camera/avfcameracontrol.h index 4d146537..bbbc8d61 100644 --- a/src/plugins/avfoundation/camera/avfcameracontrol.h +++ b/src/plugins/avfoundation/camera/avfcameracontrol.h @@ -65,7 +65,6 @@ private Q_SLOTS: void updateStatus(); private: - AVFCameraService *m_service; AVFCameraSession *m_session; QCamera::State m_state; diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.mm b/src/plugins/avfoundation/camera/avfcameracontrol.mm index bfd14a20..bef952e6 100644 --- a/src/plugins/avfoundation/camera/avfcameracontrol.mm +++ b/src/plugins/avfoundation/camera/avfcameracontrol.mm @@ -40,12 +40,12 @@ QT_USE_NAMESPACE AVFCameraControl::AVFCameraControl(AVFCameraService *service, QObject *parent) : QCameraControl(parent) - , m_service(service) , m_session(service->session()) , m_state(QCamera::UnloadedState) , m_lastStatus(QCamera::UnloadedStatus) , m_captureMode(QCamera::CaptureStillImage) { + Q_UNUSED(service); connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus())); } diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h index 8e73e677..6cc9d74e 100644 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h +++ b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h @@ -55,7 +55,6 @@ public: QStringList availableMetaData() const; private: - AVFCameraService *m_service; QMap m_tags; }; diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm index a13f6e91..36d318ef 100644 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm +++ b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm @@ -40,8 +40,9 @@ QT_USE_NAMESPACE //metadata support is not implemented yet AVFCameraMetaDataControl::AVFCameraMetaDataControl(AVFCameraService *service, QObject *parent) - :QMetaDataWriterControl(parent), m_service(service) + :QMetaDataWriterControl(parent) { + Q_UNUSED(service); } AVFCameraMetaDataControl::~AVFCameraMetaDataControl() diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h b/src/plugins/avfoundation/camera/avfimagecapturecontrol.h index c27abd39..99372565 100644 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h +++ b/src/plugins/avfoundation/camera/avfimagecapturecontrol.h @@ -66,7 +66,6 @@ private Q_SLOTS: void updateReadyStatus(); private: - AVFCameraService *m_service; AVFCameraSession *m_session; AVFCameraControl *m_cameraControl; bool m_ready; diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm index 0d245fc5..c28ccef8 100644 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm +++ b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm @@ -46,13 +46,13 @@ QT_USE_NAMESPACE AVFImageCaptureControl::AVFImageCaptureControl(AVFCameraService *service, QObject *parent) : QCameraImageCaptureControl(parent) - , m_service(service) , m_session(service->session()) , m_cameraControl(service->cameraControl()) , m_ready(false) , m_lastCaptureId(0) , m_videoConnection(nil) { + Q_UNUSED(service); m_stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: From 3c54acb6f7ab082e3c7881701b84593c6372ef6c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 3 Jun 2015 14:19:10 +0200 Subject: [PATCH 10/10] Add new property to QVideoSurfaceFormat. The 'mirrored' property indicates the QVideoFrames need to be mirrored along their vertical axis. This is typically needed for video frames coming from a front camera on a mobile device. This is implemented as a string-based property. In Qt 5.6, this should be replaced by a new public function. Change-Id: Ideb7de81e83f66826f4efb5f2951c4beec13546b Reviewed-by: Christian Stromme --- src/multimedia/video/qvideosurfaceformat.cpp | 13 +++++- .../qpaintervideosurface.cpp | 42 +++++++++++++------ .../qdeclarativevideooutput_render.cpp | 6 +++ .../tst_qvideosurfaceformat.cpp | 3 +- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index 4c616b89..df6cbcfc 100644 --- a/src/multimedia/video/qvideosurfaceformat.cpp +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -61,6 +61,7 @@ public: , pixelAspectRatio(1, 1) , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) , frameRate(0.0) + , mirrored(false) { } @@ -76,6 +77,7 @@ public: , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) , viewport(QPoint(0, 0), size) , frameRate(0.0) + , mirrored(false) { } @@ -89,6 +91,7 @@ public: , ycbcrColorSpace(other.ycbcrColorSpace) , viewport(other.viewport) , frameRate(other.frameRate) + , mirrored(other.mirrored) , propertyNames(other.propertyNames) , propertyValues(other.propertyValues) { @@ -104,6 +107,7 @@ public: && viewport == other.viewport && frameRatesEqual(frameRate, other.frameRate) && ycbcrColorSpace == other.ycbcrColorSpace + && mirrored == other.mirrored && propertyNames.count() == other.propertyNames.count()) { for (int i = 0; i < propertyNames.count(); ++i) { int j = other.propertyNames.indexOf(propertyNames.at(i)); @@ -130,6 +134,7 @@ public: QVideoSurfaceFormat::YCbCrColorSpace ycbcrColorSpace; QRect viewport; qreal frameRate; + bool mirrored; QList propertyNames; QList propertyValues; }; @@ -468,7 +473,8 @@ QList QVideoSurfaceFormat::propertyNames() const << "frameRate" << "pixelAspectRatio" << "sizeHint" - << "yCbCrColorSpace") + << "yCbCrColorSpace" + << "mirrored") + d->propertyNames; } @@ -499,6 +505,8 @@ QVariant QVideoSurfaceFormat::property(const char *name) const return sizeHint(); } else if (qstrcmp(name, "yCbCrColorSpace") == 0) { return qVariantFromValue(d->ycbcrColorSpace); + } else if (qstrcmp(name, "mirrored") == 0) { + return d->mirrored; } else { int id = 0; for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} @@ -547,6 +555,9 @@ void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value) } else if (qstrcmp(name, "yCbCrColorSpace") == 0) { if (value.canConvert()) d->ycbcrColorSpace = qvariant_cast(value); + } else if (qstrcmp(name, "mirrored") == 0) { + if (value.canConvert()) + d->mirrored = qvariant_cast(value); } else { int id = 0; for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index c9fa206a..5a8857b7 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -86,11 +86,13 @@ private: QSize m_imageSize; QImage::Format m_imageFormat; QVideoSurfaceFormat::Direction m_scanLineDirection; + bool m_mirrored; }; QVideoSurfaceGenericPainter::QVideoSurfaceGenericPainter() : m_imageFormat(QImage::Format_Invalid) , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , m_mirrored(false) { m_imagePixelFormats << QVideoFrame::Format_RGB32; @@ -137,6 +139,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::start(const QVideoSurf m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); m_imageSize = format.frameSize(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); const QAbstractVideoBuffer::HandleType t = format.handleType(); if (t == QAbstractVideoBuffer::NoHandle) { @@ -183,17 +186,22 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::paint( m_frame.bytesPerLine(), m_imageFormat); + const QTransform oldTransform = painter->transform(); + QTransform transform = oldTransform; + QRectF targetRect = target; if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) { - const QTransform oldTransform = painter->transform(); - - painter->scale(1, -1); - painter->translate(0, -target.bottom()); - painter->drawImage( - QRectF(target.x(), 0, target.width(), target.height()), image, source); - painter->setTransform(oldTransform); - } else { - painter->drawImage(target, image, source); + transform.scale(1, -1); + transform.translate(0, -target.bottom()); + targetRect.setY(0); } + if (m_mirrored) { + transform.scale(-1, 1); + transform.translate(-target.right(), 0); + targetRect.setX(0); + } + painter->setTransform(transform); + painter->drawImage(targetRect, image, source); + painter->setTransform(oldTransform); m_frame.unmap(); } else if (m_frame.isValid()) { @@ -281,6 +289,7 @@ protected: QGLContext *m_context; QAbstractVideoBuffer::HandleType m_handleType; QVideoSurfaceFormat::Direction m_scanLineDirection; + bool m_mirrored; QVideoSurfaceFormat::YCbCrColorSpace m_colorSpace; GLenum m_textureFormat; GLuint m_textureInternalFormat; @@ -299,6 +308,7 @@ QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context) : m_context(context) , m_handleType(QAbstractVideoBuffer::NoHandle) , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , m_mirrored(false) , m_colorSpace(QVideoSurfaceFormat::YCbCr_BT601) , m_textureFormat(0) , m_textureInternalFormat(0) @@ -829,6 +839,7 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac } else { m_handleType = format.handleType(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); m_frameSize = format.frameSize(); m_colorSpace = format.yCbCrColorSpace(); @@ -878,8 +889,10 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( if (scissorTestEnabled) glEnable(GL_SCISSOR_TEST); - const float txLeft = source.left() / m_frameSize.width(); - const float txRight = source.right() / m_frameSize.width(); + const float txLeft = m_mirrored ? source.right() / m_frameSize.width() + : source.left() / m_frameSize.width(); + const float txRight = m_mirrored ? source.left() / m_frameSize.width() + : source.right() / m_frameSize.width(); const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ? source.top() / m_frameSize.height() : source.bottom() / m_frameSize.height(); @@ -1188,6 +1201,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface } else { m_handleType = format.handleType(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); m_frameSize = format.frameSize(); m_colorSpace = format.yCbCrColorSpace(); @@ -1276,8 +1290,10 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( GLfloat(target.right() + 1), GLfloat(target.top()) }; - const GLfloat txLeft = source.left() / m_frameSize.width(); - const GLfloat txRight = source.right() / m_frameSize.width(); + const GLfloat txLeft = m_mirrored ? source.right() / m_frameSize.width() + : source.left() / m_frameSize.width(); + const GLfloat txRight = m_mirrored ? source.left() / m_frameSize.width() + : source.right() / m_frameSize.width(); const GLfloat txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ? source.top() / m_frameSize.height() : source.bottom() / m_frameSize.height(); diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp index de4cabfa..70d48dd9 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp @@ -255,6 +255,12 @@ void QDeclarativeVideoRendererBackend::updateGeometry() m_sourceTextureRect.setTop(m_sourceTextureRect.bottom()); m_sourceTextureRect.setBottom(top); } + + if (videoSurface()->surfaceFormat().property("mirrored").toBool()) { + qreal left = m_sourceTextureRect.left(); + m_sourceTextureRect.setLeft(m_sourceTextureRect.right()); + m_sourceTextureRect.setRight(left); + } } QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode, diff --git a/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp b/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp index 8e548d64..6ad87597 100644 --- a/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp +++ b/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp @@ -521,7 +521,8 @@ void tst_QVideoSurfaceFormat::staticPropertyNames() QVERIFY(propertyNames.contains("pixelAspectRatio")); QVERIFY(propertyNames.contains("yCbCrColorSpace")); QVERIFY(propertyNames.contains("sizeHint")); - QCOMPARE(propertyNames.count(), 10); + QVERIFY(propertyNames.contains("mirrored")); + QCOMPARE(propertyNames.count(), 11); } void tst_QVideoSurfaceFormat::dynamicProperty()