From e207134ff862e4aeb250e319f67c283b5c1d6f24 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 14 Oct 2019 09:41:41 +0200 Subject: Bump version Change-Id: Ic40941bd63720eb1d753abd457f5861782f99105 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 1ed62c5ac..543d0a842 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.13.1 +MODULE_VERSION = 5.13.2 -- cgit v1.2.3 From dce51b45e8d50ad37fea3debb51a84d62e944b5d Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Mon, 14 Oct 2019 10:28:57 +0300 Subject: Add changes file for Qt 5.13.2 Change-Id: I4cc304daa4098bd1209152bb84cae7ee93d92933 Reviewed-by: Andy Shaw --- dist/changes-5.13.2 | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 dist/changes-5.13.2 diff --git a/dist/changes-5.13.2 b/dist/changes-5.13.2 new file mode 100644 index 000000000..62dffcb02 --- /dev/null +++ b/dist/changes-5.13.2 @@ -0,0 +1,68 @@ +Qt 5.13.2 is a bug-fix release. It maintains both forward and backward +source compatibility with Qt 5.13.0 through 5.13.1. +In Qt 5.13.0, binary compatibility was broken due to the usage of the enum +QVideoFrame::PixelFormat, the break has been reverted, +thus introducing a binary compatibility break with earlier Qt 5.13.0 and 5.13.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.13.2 Changes * +**************************************************************************** + + - In Qt 5.13.0 binary compatibility was broken + for usage of the enum QVideoFrame::PixelFormat by introducing + QVideoFrame::Format_ABGR32. + To minimize the impact of this, the break has been reverted, + thus introducing a binary compatibility break with earlier Qt 5.13.x + versions, but restoring compatibility with all earlier versions of Qt 5. + - Fixed crash when VideoOutput.sourceRect is requested but playback is stopped. + - [QTBUG-51588] Fixed leaking of QVideoFilterRunnable when window is closed. + - [QTBUG-45064] Introduced QGraphicsVideoItem::type(). + - Fixed camera.viewfinder to respect camera's media status + if the viewfinder is requested after the camera is loaded. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + - GStreamer: + * CameraBin plugin now fetches supported viewfinder settings at status + higher or equal to LoadedStatus if it has not been fetched. + * Fixed duplicated entries in supported Camera's resolution/framerate if the + underlying element uses caps' features. + * Introduced audio/x-raw codec in QAudioRecorder. + * [QTBUG-65399] Fixed media player to show pre-rolled frame on new media + (means to seek to the beginning) only when pause() is called. + * [QTBUG-76135] Show image processing warnings only when the camera is loaded. + * [QTBUG-78079] Fixed media player to recreate playbin features after custom pipeline. + * [QTBUG-73084] Fixed mapping of VPU texture using real physical address of data + which prevents leaks in the kernel for iMX boards. + + - AVFoundation: + * [QTBUG-77270] Fixed black frames being shown if current OpenGL context has been changed. + * [QTBUG-49806] Fixed media player to send StalledMedia status when no enough data to play + and resume playback afterwards. + + - DirectShow: + * [QTBUG-77829] Fixed crash when there is no surface on flush(). + * [QTBUG-77849] Introduced startTime and endTime to QVideoFrame. + * [QTBUG-77163] Introduced support to use QMediaPlayer in secondary thread. + * [QTBUG-46368] Implemented QMediaVideoProbeControl->flush(). + * [QTBUG-46368] Fixed media player to send media status before errors. + * [QTBUG-68778] Fixed media player to postpone seeking if the playback is stopped. + * Fixed crash when qrc media resource is set twice to media player. -- cgit v1.2.3 From 327e2c7a84e11420376a6257aeebed035d430833 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 23 Oct 2019 11:23:30 +0200 Subject: QMediaPlayList: use new style connect syntax Change-Id: Idf13b2f851b78a9134b0c22ec9333f28f5b265cf Reviewed-by: VaL Doroshchuk --- src/multimedia/playback/qmediaplaylist.cpp | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/multimedia/playback/qmediaplaylist.cpp b/src/multimedia/playback/qmediaplaylist.cpp index 7c21a599b..9539a1809 100644 --- a/src/multimedia/playback/qmediaplaylist.cpp +++ b/src/multimedia/playback/qmediaplaylist.cpp @@ -184,20 +184,20 @@ bool QMediaPlaylist::setMediaObject(QMediaObject *mediaObject) disconnect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)), this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString))); - disconnect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int))); - disconnect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int))); - disconnect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int))); - disconnect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int))); - disconnect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int))); + disconnect(playlist, &QMediaPlaylistProvider::mediaChanged, this, &QMediaPlaylist::mediaChanged); + disconnect(playlist, &QMediaPlaylistProvider::mediaAboutToBeInserted, this, &QMediaPlaylist::mediaAboutToBeInserted); + disconnect(playlist, &QMediaPlaylistProvider::mediaInserted, this, &QMediaPlaylist::mediaInserted); + disconnect(playlist, &QMediaPlaylistProvider::mediaAboutToBeRemoved, this, &QMediaPlaylist::mediaAboutToBeRemoved); + disconnect(playlist, &QMediaPlaylistProvider::mediaRemoved, this, &QMediaPlaylist::mediaRemoved); - disconnect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded())); + disconnect(playlist, &QMediaPlaylistProvider::loaded, this, &QMediaPlaylist::loaded); - disconnect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)), - this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); - disconnect(d->control, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - disconnect(d->control, SIGNAL(currentMediaChanged(QMediaContent)), - this, SIGNAL(currentMediaChanged(QMediaContent))); + disconnect(d->control, &QMediaPlaylistControl::playbackModeChanged, + this, &QMediaPlaylist::playbackModeChanged); + disconnect(d->control, &QMediaPlaylistControl::currentIndexChanged, + this, &QMediaPlaylist::currentIndexChanged); + disconnect(d->control, &QMediaPlaylistControl::currentMediaChanged, + this, &QMediaPlaylist::currentMediaChanged); // Copy playlist items, sync playback mode and sync current index between // old control and new control @@ -214,20 +214,20 @@ bool QMediaPlaylist::setMediaObject(QMediaObject *mediaObject) connect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)), this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString))); - connect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int))); - connect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int))); - connect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int))); - connect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int))); - connect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int))); + connect(playlist, &QMediaPlaylistProvider::mediaChanged, this, &QMediaPlaylist::mediaChanged); + connect(playlist, &QMediaPlaylistProvider::mediaAboutToBeInserted, this, &QMediaPlaylist::mediaAboutToBeInserted); + connect(playlist, &QMediaPlaylistProvider::mediaInserted, this, &QMediaPlaylist::mediaInserted); + connect(playlist, &QMediaPlaylistProvider::mediaAboutToBeRemoved, this, &QMediaPlaylist::mediaAboutToBeRemoved); + connect(playlist, &QMediaPlaylistProvider::mediaRemoved, this, &QMediaPlaylist::mediaRemoved); - connect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded())); + connect(playlist, &QMediaPlaylistProvider::loaded, this, &QMediaPlaylist::loaded); - connect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)), - this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); - connect(d->control, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - connect(d->control, SIGNAL(currentMediaChanged(QMediaContent)), - this, SIGNAL(currentMediaChanged(QMediaContent))); + connect(d->control, &QMediaPlaylistControl::playbackModeChanged, + this, &QMediaPlaylist::playbackModeChanged); + connect(d->control, &QMediaPlaylistControl::currentIndexChanged, + this, &QMediaPlaylist::currentIndexChanged); + connect(d->control, &QMediaPlaylistControl::currentMediaChanged, + this, &QMediaPlaylist::currentMediaChanged); if (removedStart != -1 && removedEnd != -1) { emit mediaAboutToBeRemoved(removedStart, removedEnd); -- cgit v1.2.3 From a6ae689d636bfcb170333f27cddb0375aeea1dbf Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 4 Sep 2019 12:37:12 +0200 Subject: Build without OpenGL support There is support for rendering video without OpenGL on most platforms although some features are unavailable as a result, so we can make sure that what is available can be used. Change-Id: I63938e8e4e8063fcc2064d0f9d8d5f10e0fb06f9 Reviewed-by: VaL Doroshchuk --- .../qdeclarativevideooutput.cpp | 5 ++++- .../qtmultimediaquicktools.pro | 23 ++++++++++++---------- src/src.pro | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index 18cf0e927..74c83246f 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -206,6 +206,7 @@ void QDeclarativeVideoOutput::setSource(QObject *source) } m_sourceType = MediaObjectSource; +#if QT_CONFIG(opengl) } else if (metaObject->indexOfProperty("videoSurface") != -1) { // Make sure our backend is a QDeclarativeVideoRendererBackend m_backend.reset(); @@ -219,6 +220,7 @@ void QDeclarativeVideoOutput::setSource(QObject *source) m_source.data()->setProperty("videoSurface", QVariant::fromValue(surface)); m_sourceType = VideoSurfaceSource; +#endif } else { m_sourceType = NoSource; } @@ -247,12 +249,13 @@ bool QDeclarativeVideoOutput::createBackend(QMediaService *service) } } } - +#if QT_CONFIG(opengl) if (!backendAvailable) { m_backend.reset(new QDeclarativeVideoRendererBackend(this)); if (m_backend->init(service)) backendAvailable = true; } +#endif // QDeclarativeVideoWindowBackend only works when there is a service with a QVideoWindowControl. // Without service, the QDeclarativeVideoRendererBackend should always work. diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro index bffdc6ec2..fd29ee5a4 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro @@ -16,20 +16,23 @@ PRIVATE_HEADERS += \ HEADERS += \ $$PRIVATE_HEADERS \ - qdeclarativevideooutput_render_p.h \ - qdeclarativevideooutput_window_p.h \ - qsgvideonode_yuv_p.h \ - qsgvideonode_rgb_p.h \ - qsgvideonode_texture_p.h + qdeclarativevideooutput_window_p.h SOURCES += \ qsgvideonode_p.cpp \ qdeclarativevideooutput.cpp \ - qdeclarativevideooutput_render.cpp \ - qdeclarativevideooutput_window.cpp \ - qsgvideonode_yuv.cpp \ - qsgvideonode_rgb.cpp \ - qsgvideonode_texture.cpp + qdeclarativevideooutput_window.cpp + +qtConfig(opengl) { + SOURCES += qdeclarativevideooutput_render.cpp \ + qsgvideonode_rgb.cpp \ + qsgvideonode_yuv.cpp \ + qsgvideonode_texture.cpp + HEADERS += qdeclarativevideooutput_render_p.h \ + qsgvideonode_rgb_p.h \ + qsgvideonode_yuv_p.h \ + qsgvideonode_texture_p.h +} RESOURCES += \ qtmultimediaquicktools.qrc diff --git a/src/src.pro b/src/src.pro index 97a053379..1dc1015c6 100644 --- a/src/src.pro +++ b/src/src.pro @@ -16,7 +16,7 @@ src_plugins.subdir = plugins src_plugins.depends = multimedia -qtHaveModule(quick):qtConfig(opengl) { +qtHaveModule(quick) { src_qtmultimediaquicktools.subdir = qtmultimediaquicktools src_qtmultimediaquicktools.depends = multimedia -- cgit v1.2.3 From b64bdf32ce10b039e8d7b1be18d001e89f315615 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 1 Nov 2019 14:11:41 +0100 Subject: Qt Mumtimedia - fix build for iOS Since RestrictedBool conversion operator was introduced, objective-C method calls require explicit .data() on our smart pointers. Fixes: QTBUG-79686 Change-Id: Ie32ebf0442cd56a01466aa58b89651d7c293de6d Reviewed-by: VaL Doroshchuk --- src/plugins/avfoundation/camera/avfmediaassetwriter.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm index 318d66117..9030adb2c 100644 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm +++ b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm @@ -413,7 +413,7 @@ enum WriterState m_audioOutput.reset([[AVCaptureAudioDataOutput alloc] init]); - if (m_audioOutput && [captureSession canAddOutput:m_audioOutput]) { + if (m_audioOutput.data() && [captureSession canAddOutput:m_audioOutput]) { [captureSession addOutput:m_audioOutput]; } else { qDebugCamera() << Q_FUNC_INFO << "failed to add audio output"; @@ -431,7 +431,7 @@ enum WriterState { Q_ASSERT(m_service && m_service->videoOutput() && m_service->videoOutput()->videoDataOutput()); - Q_ASSERT(m_assetWriter); + Q_ASSERT(m_assetWriter.data()); m_cameraWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:m_videoSettings @@ -451,7 +451,7 @@ enum WriterState m_cameraWriterInput.data().expectsMediaDataInRealTime = YES; - if (m_audioOutput) { + if (m_audioOutput.data()) { CMFormatDescriptionRef sourceFormat = m_audioCaptureDevice ? m_audioCaptureDevice.activeFormat.formatDescription : 0; m_audioWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:m_audioSettings @@ -479,7 +479,7 @@ enum WriterState [m_service->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue]; - if (m_audioOutput) { + if (m_audioOutput.data()) { Q_ASSERT(m_audioQueue); [m_audioOutput setSampleBufferDelegate:self queue:m_audioQueue]; } -- cgit v1.2.3 From 8b92454d6fffcee7a8cf1fb5e0c92920c77733c8 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 25 Oct 2019 12:29:34 +0200 Subject: ALSA: Calculate buffer size based on min period time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When defualt buffer size (100000us) and period time (20000us) are out of range, currently buffer size is computed with respect of either 2 or 4 chunks of maximum buffer time. Which is not enough. Fixing computing of buffer time based on minimum period time: How many minimum periods could fit in maximum suggested buffer time. Fixes: QTBUG-43256 Task-number: QTBUG-79526 Change-Id: I722e5145e3b6d323e306da420ec764db3575225f Reviewed-by: Christian Strømme --- src/plugins/alsa/qalsaaudiooutput.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp index ddbe04de9..5c8ae171c 100644 --- a/src/plugins/alsa/qalsaaudiooutput.cpp +++ b/src/plugins/alsa/qalsaaudiooutput.cpp @@ -53,9 +53,11 @@ #include #include "qalsaaudiooutput.h" #include "qalsaaudiodeviceinfo.h" +#include QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcAlsaOutput, "qt.multimedia.alsa.output") //#define DEBUG_AUDIO 1 QAlsaAudioOutput::QAlsaAudioOutput(const QByteArray &device) @@ -403,28 +405,22 @@ bool QAlsaAudioOutput::open() fatal = true; errMessage = QString::fromLatin1("QAudioOutput: buffer/period min and max: err = %1").arg(err); } else { - if (maxBufferTime < buffer_time || buffer_time < minBufferTime || maxPeriodTime < period_time || minPeriodTime > period_time) { -#ifdef DEBUG_AUDIO - qDebug()<<"defaults out of range"; - qDebug()<<"pmin="< period_time; + if (outOfRange || user_period_time || user_buffer_time) { + period_time = user_period_time ? user_period_time : minPeriodTime; + if (!user_buffer_time) { + chunks = maxBufferTime / period_time; + buffer_time = period_time * chunks; } else { - qWarning()<<"QAudioOutput: alsa only supports single period!"; - fatal = true; + buffer_time = user_buffer_time; + chunks = buffer_time / period_time; } -#ifdef DEBUG_AUDIO - qDebug()<<"used: buffer_time="< -#include #include @@ -52,17 +51,10 @@ QT_BEGIN_NAMESPACE class AVFMediaRecorderControlIOS; class AVFCameraService; -typedef QAtomicInteger AVFAtomicInt64; - QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) : NSObject -{ -@public - QT_PREPEND_NAMESPACE(AVFAtomicInt64) m_durationInMs; -} - - (id)initWithDelegate:(QT_PREPEND_NAMESPACE(AVFMediaRecorderControlIOS) *)delegate; - (bool)setupWithFileURL:(NSURL *)fileURL @@ -76,6 +68,7 @@ QT_END_NAMESPACE - (void)stop; // This to be called from the recorder control's dtor: - (void)abort; +- (qint64)durationInMs; @end diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm index 9030adb2c..2d40b9087 100644 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm +++ b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm @@ -47,6 +47,7 @@ #include "avfmediacontainercontrol.h" #include +#include QT_USE_NAMESPACE @@ -79,6 +80,8 @@ enum WriterState WriterStateAborted }; +using AVFAtomicInt64 = QAtomicInteger; + } // unnamed namespace @interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) (PrivateAPI) @@ -93,32 +96,35 @@ enum WriterState @private AVFCameraService *m_service; - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_cameraWriterInput; - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_audioInput; - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_audioOutput; - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_audioWriterInput; + AVFScopedPointer m_cameraWriterInput; + AVFScopedPointer m_audioInput; + AVFScopedPointer m_audioOutput; + AVFScopedPointer m_audioWriterInput; + AVCaptureDevice *m_audioCaptureDevice; // Queue to write sample buffers: - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_writerQueue; + AVFScopedPointer m_writerQueue; // High priority serial queue for video output: - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_videoQueue; + AVFScopedPointer m_videoQueue; // Serial queue for audio output: - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_audioQueue; + AVFScopedPointer m_audioQueue; - QT_PREPEND_NAMESPACE(AVFScopedPointer) m_assetWriter; + AVFScopedPointer m_assetWriter; - QT_PREPEND_NAMESPACE(AVFMediaRecorderControlIOS) *m_delegate; + AVFMediaRecorderControlIOS *m_delegate; bool m_setStartTime; - QT_PREPEND_NAMESPACE(QAtomicInt) m_state; -@private + QAtomicInt m_state; + CMTime m_startTime; CMTime m_lastTimeStamp; NSDictionary *m_audioSettings; NSDictionary *m_videoSettings; + + AVFAtomicInt64 m_durationInMs; } - (id)initWithDelegate:(AVFMediaRecorderControlIOS *)delegate @@ -500,4 +506,9 @@ enum WriterState } } +- (qint64)durationInMs +{ + return m_durationInMs.loadAcquire(); +} + @end diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm index 0b31bd0bc..62197e900 100644 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm +++ b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm @@ -144,7 +144,7 @@ QMediaRecorder::Status AVFMediaRecorderControlIOS::status() const qint64 AVFMediaRecorderControlIOS::duration() const { - return m_writer.data()->m_durationInMs.load(); + return m_writer.data().durationInMs; } bool AVFMediaRecorderControlIOS::isMuted() const -- cgit v1.2.3 From 4d251f072c6f97b4cf4618103e4e857e499c5ed7 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 5 Nov 2019 13:39:55 +0100 Subject: GStreamer: Fix crash when video sink is used when it has been destroyed When custom pipeline is requested, all playbin related elements must be cleared. Also when QMediaPlayer is destroying, it disables showing preroll frames, property of the video sink, which was already destroyed. Destroying of m_videoOutputBin decreases refcounter for m_videoSink, since the video sink is owned by m_videoOutputBin. Fixes: QTBUG-79753 Change-Id: I2fcbd19372caf46adf2ae1ed2e5a7d0ee70040ad Reviewed-by: Timur Pocheptsov --- src/gsttools/qgstreamerplayersession.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp index c0998d7ae..05e419b10 100644 --- a/src/gsttools/qgstreamerplayersession.cpp +++ b/src/gsttools/qgstreamerplayersession.cpp @@ -252,8 +252,11 @@ void QGstreamerPlayerSession::resetElements() resetGstObject(m_nullVideoSink); resetGstObject(m_videoOutputBin); + m_audioSink = nullptr; m_volumeElement = nullptr; m_videoIdentity = nullptr; + m_pendingVideoSink = nullptr; + m_videoSink = nullptr; } GstElement *QGstreamerPlayerSession::playbin() const -- cgit v1.2.3 From fc2029e9fe621a1ceaa67fbc1d32b3150fd0b262 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 9 Oct 2019 10:51:59 -0700 Subject: opensl: support android voice comm preset in order to trigger aec OpenSL ES support acoustic echo cancellation via the SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION preset, but this isn't exposed through Qt's wrapping layer. This change exposes new Qt constants to enable the use of this feature Change-Id: Ie64a949313b5a5b35d24159d3549290893ce32dd Fixes: QTBUG-70368 Reviewed-by: VaL Doroshchuk --- src/plugins/opensles/qopenslesaudioinput.cpp | 2 ++ src/plugins/opensles/qopenslesaudioinput.h | 1 + src/plugins/opensles/qopenslesengine.cpp | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp index ad87cb057..54ed18ac1 100644 --- a/src/plugins/opensles/qopenslesaudioinput.cpp +++ b/src/plugins/opensles/qopenslesaudioinput.cpp @@ -117,6 +117,8 @@ QOpenSLESAudioInput::QOpenSLESAudioInput(const QByteArray &device) m_recorderPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER; else if (qstrcmp(device, QT_ANDROID_PRESET_VOICE_RECOGNITION) == 0) m_recorderPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + else if (qstrcmp(device, QT_ANDROID_PRESET_VOICE_COMMUNICATION) == 0) + m_recorderPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; else m_recorderPreset = SL_ANDROID_RECORDING_PRESET_GENERIC; #endif diff --git a/src/plugins/opensles/qopenslesaudioinput.h b/src/plugins/opensles/qopenslesaudioinput.h index ad84db0cd..35cc37959 100644 --- a/src/plugins/opensles/qopenslesaudioinput.h +++ b/src/plugins/opensles/qopenslesaudioinput.h @@ -50,6 +50,7 @@ #define QT_ANDROID_PRESET_MIC "mic" #define QT_ANDROID_PRESET_CAMCORDER "camcorder" #define QT_ANDROID_PRESET_VOICE_RECOGNITION "voicerecognition" +#define QT_ANDROID_PRESET_VOICE_COMMUNICATION "voicecommunication" #endif diff --git a/src/plugins/opensles/qopenslesengine.cpp b/src/plugins/opensles/qopenslesengine.cpp index 43cdcb276..36025dcfd 100644 --- a/src/plugins/opensles/qopenslesengine.cpp +++ b/src/plugins/opensles/qopenslesengine.cpp @@ -114,7 +114,8 @@ QList QOpenSLESEngine::availableDevices(QAudio::Mode mode) const #ifdef ANDROID devices << QT_ANDROID_PRESET_MIC << QT_ANDROID_PRESET_CAMCORDER - << QT_ANDROID_PRESET_VOICE_RECOGNITION; + << QT_ANDROID_PRESET_VOICE_RECOGNITION + << QT_ANDROID_PRESET_VOICE_COMMUNICATION; #else devices << "default"; #endif -- cgit v1.2.3 From 3d33ebd547d5cdc16e6f8700282035ac3b96e604 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 18 Sep 2019 17:21:16 +0200 Subject: QGstreamerPlayerControl: do not touch m_mediaStatus if it is EndOfMedia It would be reset to this state at the end of updateMediaStatus() anyway, so simply leave it alone. Change-Id: I7fa24773ebb1dd43ecfa8d7eb28d6f8e7862fa75 Reviewed-by: VaL Doroshchuk --- src/gsttools/qgstreamerplayercontrol.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gsttools/qgstreamerplayercontrol.cpp b/src/gsttools/qgstreamerplayercontrol.cpp index 7c96b682f..c6fd184ef 100644 --- a/src/gsttools/qgstreamerplayercontrol.cpp +++ b/src/gsttools/qgstreamerplayercontrol.cpp @@ -454,6 +454,10 @@ void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state) void QGstreamerPlayerControl::updateMediaStatus() { + //EndOfMedia status should be kept, until reset by pause, play or setMedia + if (m_mediaStatus == QMediaPlayer::EndOfMedia) + return; + pushState(); QMediaPlayer::MediaStatus oldStatus = m_mediaStatus; @@ -481,10 +485,6 @@ void QGstreamerPlayerControl::updateMediaStatus() if (m_currentState == QMediaPlayer::PlayingState && !m_resources->isGranted()) m_mediaStatus = QMediaPlayer::StalledMedia; - //EndOfMedia status should be kept, until reset by pause, play or setMedia - if (oldStatus == QMediaPlayer::EndOfMedia) - m_mediaStatus = QMediaPlayer::EndOfMedia; - popAndNotifyState(); } -- cgit v1.2.3 From f9a576826c0d770aaae8aadbedaf83e1c0b72e0a Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 26 Jul 2018 15:08:28 +0200 Subject: Android: Fix fetching video frame data from the GUI thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If QAbstractVideoSurface is not used on rendering thread added a way to pass shared opengl context via GLContext surface property. Camera and media players that are created in Qt Quick will usually have their rendering done on the render thread, but the callback for custom video surface(s) (or probes) will usually be handle on the GUI thread, so to make it convenient to for the user to access the frame data, which is rendered on request, we now set-up context sharing and render to a fbo on the calling thread, if needed. Task-number: QTBUG-69333 Change-Id: I4cc5c1f741c82376f1402a047b946b59281c9a4c Reviewed-by: Christian Strømme --- .../android/src/common/qandroidvideooutput.cpp | 33 ++++++++++++++++++++++ .../android/src/common/qandroidvideooutput.h | 5 ++++ 2 files changed, 38 insertions(+) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index 083ceff24..a4f4dbd5d 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -49,6 +49,8 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE @@ -182,6 +184,8 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput() { + delete m_offscreenSurface; + delete m_glContext; clearSurfaceTexture(); if (m_glDeleter) { // Make sure all of these are deleted on the render thread. @@ -345,6 +349,35 @@ bool QAndroidTextureVideoOutput::renderFrameToFbo() if (!m_nativeSize.isValid() || !m_surfaceTexture) return false; + // Make sure we have an OpenGL context to make current. + if (!QOpenGLContext::currentContext() && !m_glContext) { + // Create Hidden QWindow surface to create context in this thread. + m_offscreenSurface = new QWindow(); + m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface); + // Needs geometry to be a valid surface, but size is not important. + m_offscreenSurface->setGeometry(0, 0, 1, 1); + m_offscreenSurface->create(); + + // Create OpenGL context and set share context from surface. + m_glContext = new QOpenGLContext(); + m_glContext->setFormat(m_offscreenSurface->requestedFormat()); + + auto surface = qobject_cast(m_surface->property("videoSurface").value()); + if (!surface) + surface = m_surface; + auto shareContext = qobject_cast(surface->property("GLContext").value()); + if (shareContext) + m_glContext->setShareContext(shareContext); + + if (!m_glContext->create()) { + qWarning("Failed to create QOpenGLContext"); + return false; + } + } + + if (m_glContext) + m_glContext->makeCurrent(m_offscreenSurface); + createGLResources(); m_surfaceTexture->updateTexImage(); diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index 2a35247e9..456fe8e22 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -51,6 +51,8 @@ class AndroidSurfaceHolder; class QOpenGLFramebufferObject; class QOpenGLShaderProgram; class QAbstractVideoSurface; +class QWindow; +class QOpenGLContext; class QAndroidVideoOutput : public QObject { @@ -132,6 +134,9 @@ private: bool m_surfaceTextureCanAttachToContext; + QWindow *m_offscreenSurface = nullptr; + QOpenGLContext *m_glContext = nullptr; + friend class AndroidTextureVideoBuffer; }; -- cgit v1.2.3 From 2eabff2d4a8fb4afc9ab3eb06bfddf8ffc0ba2b2 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 12 Nov 2019 11:42:26 +0100 Subject: Doc: Fix documentation warnings Mark member functions of \internal classes also as \internal, as otherwise QDoc fails to match function documentation with the declaration in the header. Comment out one instance of \instantiates referring to an internal class. Fixes: QTBUG-79834 Change-Id: I056c060537ee60beca128166ae3903ae3289a413 Reviewed-by: Venugopal Shivashankar Reviewed-by: Paul Wicking --- src/multimedia/qmediaserviceprovider.cpp | 11 +++++++++++ src/qtmultimediaquicktools/qdeclarativevideooutput.cpp | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/multimedia/qmediaserviceprovider.cpp b/src/multimedia/qmediaserviceprovider.cpp index 5731cf5be..d8ffe42ae 100644 --- a/src/multimedia/qmediaserviceprovider.cpp +++ b/src/multimedia/qmediaserviceprovider.cpp @@ -682,6 +682,7 @@ Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider); */ /*! + \internal \fn QMediaServiceProvider::requestService(const QByteArray &type, const QMediaServiceProviderHint &hint) Requests an instance of a \a type service which best matches the given \a @@ -695,12 +696,14 @@ Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider); */ /*! + \internal \fn QMediaServiceProvider::releaseService(QMediaService *service) Releases a media \a service requested with requestService(). */ /*! + \internal \fn QMediaServiceProvider::supportedFeatures(const QMediaService *service) const Returns the features supported by a given \a service. @@ -713,6 +716,7 @@ QMediaServiceProviderHint::Features QMediaServiceProvider::supportedFeatures(con } /*! + \internal Returns how confident a media service provider is that is can provide a \a serviceType service that is able to play media of a specific \a mimeType that is encoded using the listed \a codecs while adhering to constraints @@ -732,6 +736,7 @@ QMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray } /*! + \internal \fn QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const Returns a list of MIME types supported by the service provider for the @@ -749,6 +754,7 @@ QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceT } /*! + \internal \since 5.3 Returns the default device for a \a service type. @@ -760,6 +766,7 @@ QByteArray QMediaServiceProvider::defaultDevice(const QByteArray &serviceType) c } /*! + \internal Returns the list of devices related to \a service type. */ QList QMediaServiceProvider::devices(const QByteArray &service) const @@ -769,6 +776,7 @@ QList QMediaServiceProvider::devices(const QByteArray &service) cons } /*! + \internal Returns the description of \a device related to \a serviceType, suitable for use by an application for display. */ @@ -780,6 +788,7 @@ QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType, } /*! + \internal \since 5.3 Returns the physical position of a camera \a device on the system hardware. @@ -791,6 +800,7 @@ QCamera::Position QMediaServiceProvider::cameraPosition(const QByteArray &device } /*! + \internal \since 5.3 Returns the physical orientation of the camera \a device. The value is the angle by which the @@ -818,6 +828,7 @@ void QMediaServiceProvider::setDefaultServiceProvider(QMediaServiceProvider *pro /*! + \internal Returns a default provider of media services. */ QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider() diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index 74c83246f..32166502d 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -57,7 +57,7 @@ Q_LOGGING_CATEGORY(qLcVideo, "qt.multimedia.video") /*! \qmltype VideoOutput - \instantiates QDeclarativeVideoOutput + //! \instantiates QDeclarativeVideoOutput \brief Render video or camera viewfinder. \ingroup multimedia_qml -- cgit v1.2.3 From 72fdf4b20e916ea87b334be1a35235ac1023e0d8 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 13 Nov 2019 11:05:48 +0100 Subject: Android: Don't close camera when recording permission is asked If camera permission is granted and recording is requested it also requires recording audio permission. If it was not granted before the popup will be shown to ask the user to grant the permission and the app goes to inactive state, which destroys the camera handlers. When the camera is loaded but the app requires additional permissions, it should not destroy the camera. Change-Id: Iee3662a7ac3381b0eb29190779b0116f9f64304f Fixes: QTBUG-79909 Reviewed-by: Volker Hilsheimer --- src/plugins/android/src/common/qandroidmultimediautils.cpp | 5 +++++ src/plugins/android/src/common/qandroidmultimediautils.h | 1 + .../android/src/mediacapture/qandroidcamerasession.cpp | 11 ++++++++++- src/plugins/android/src/mediacapture/qandroidcamerasession.h | 2 ++ .../android/src/mediacapture/qandroidcapturesession.cpp | 6 ++++-- src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp | 5 ----- src/plugins/android/src/wrappers/jni/androidmediarecorder.h | 1 - 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp index a4a7f773d..fa6e7da65 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.cpp +++ b/src/plugins/android/src/common/qandroidmultimediautils.cpp @@ -139,4 +139,9 @@ bool qt_androidRequestPermission(const QString &key) return true; } +bool qt_androidRequestRecordingPermission() +{ + return qt_androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h index 0a837ae3c..bbd2e9aa5 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.h +++ b/src/plugins/android/src/common/qandroidmultimediautils.h @@ -56,6 +56,7 @@ QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::Ima AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f); bool qt_androidRequestPermission(const QString &key); +bool qt_androidRequestRecordingPermission(); QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 6a30e5300..9de3330c7 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -78,6 +78,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) , m_captureCanceled(false) , m_currentImageCaptureId(-1) , m_previewCallback(0) + , m_keepActive(false) { m_mediaStorageLocation.addStorageLocation( QMediaStorageLocation::Pictures, @@ -913,7 +914,7 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state { switch (state) { case Qt::ApplicationInactive: - if (m_state != QCamera::UnloadedState) { + if (!m_keepActive && m_state != QCamera::UnloadedState) { m_savedState = m_state; close(); m_state = QCamera::UnloadedState; @@ -931,4 +932,12 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state } } +bool QAndroidCameraSession::requestRecordingPermission() +{ + m_keepActive = true; + const bool result = qt_androidRequestRecordingPermission(); + m_keepActive = false; + return result; +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index b51dcc628..728dc484e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -112,6 +112,7 @@ public: virtual void onFrameAvailable(const QVideoFrame &frame) = 0; }; void setPreviewCallback(PreviewCallback *callback); + bool requestRecordingPermission(); Q_SIGNALS: void statusChanged(QCamera::Status status); @@ -196,6 +197,7 @@ private: QSet m_videoProbes; QMutex m_videoProbesMutex; PreviewCallback *m_previewCallback; + bool m_keepActive; }; QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index bc9bc983e..7cc3ad619 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -206,8 +206,10 @@ void QAndroidCaptureSession::start() delete m_mediaRecorder; } - - if (!AndroidMediaRecorder::requestRecordingPermission()) { + const bool granted = m_cameraSession + ? m_cameraSession->requestRecordingPermission() + : qt_androidRequestRecordingPermission(); + if (!granted) { setStatus(QMediaRecorder::UnavailableStatus); Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Permission denied.")); return; diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp index d0101411b..d607ab806 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp @@ -383,11 +383,6 @@ void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder) } } -bool AndroidMediaRecorder::requestRecordingPermission() -{ - return qt_androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); -} - bool AndroidMediaRecorder::initJNI(JNIEnv *env) { jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName, diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h index cd2d164d8..e4b3a80ea 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h @@ -160,7 +160,6 @@ public: void setSurfaceTexture(AndroidSurfaceTexture *texture); void setSurfaceHolder(AndroidSurfaceHolder *holder); - static bool requestRecordingPermission(); static bool initJNI(JNIEnv *env); Q_SIGNALS: -- cgit v1.2.3 From 49bf444b44dac10602af0af862f0951835ea5895 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 15 Nov 2019 10:47:17 +0100 Subject: Android: Remove usage of qt_androidRequestPermission Use specific function instead, e.g. qt_androidRequestCameraPermission. Change-Id: I925e4d8ac4f1993c073930a79453894dd516d769 Reviewed-by: Volker Hilsheimer --- .../android/src/common/qandroidmultimediautils.cpp | 9 +++++++-- src/plugins/android/src/common/qandroidmultimediautils.h | 2 +- .../android/src/mediacapture/qandroidcamerasession.cpp | 2 +- src/plugins/android/src/wrappers/jni/androidcamera.cpp | 15 ++++----------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp index fa6e7da65..1f03d5d29 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.cpp +++ b/src/plugins/android/src/common/qandroidmultimediautils.cpp @@ -113,7 +113,7 @@ AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::Pix } } -bool qt_androidRequestPermission(const QString &key) +static bool androidRequestPermission(const QString &key) { using namespace QtAndroidPrivate; @@ -139,9 +139,14 @@ bool qt_androidRequestPermission(const QString &key) return true; } +bool qt_androidRequestCameraPermission() +{ + return androidRequestPermission(QLatin1String("android.permission.CAMERA")); +} + bool qt_androidRequestRecordingPermission() { - return qt_androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); + return androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO")); } QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h index bbd2e9aa5..381671cb8 100644 --- a/src/plugins/android/src/common/qandroidmultimediautils.h +++ b/src/plugins/android/src/common/qandroidmultimediautils.h @@ -55,7 +55,7 @@ bool qt_sizeLessThan(const QSize &s1, const QSize &s2); QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f); AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f); -bool qt_androidRequestPermission(const QString &key); +bool qt_androidRequestCameraPermission(); bool qt_androidRequestRecordingPermission(); QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 9de3330c7..f3ad84836 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -184,7 +184,7 @@ bool QAndroidCameraSession::open() m_status = QCamera::LoadingStatus; emit statusChanged(m_status); - m_camera = AndroidCamera::requestCameraPermission() ? AndroidCamera::open(m_selectedCamera) : nullptr; + m_camera = AndroidCamera::open(m_selectedCamera); if (m_camera) { connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 2f32fb742..3ea7bc773 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -58,11 +58,6 @@ QT_BEGIN_NAMESPACE static const char QtCameraListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtCameraListener"; -static QString cameraPermissionKey() -{ - return QStringLiteral("android.permission.CAMERA"); -} - typedef QHash CameraMap; Q_GLOBAL_STATIC(CameraMap, cameras) Q_GLOBAL_STATIC(QReadWriteLock, rwLock) @@ -324,6 +319,9 @@ AndroidCamera::~AndroidCamera() AndroidCamera *AndroidCamera::open(int cameraId) { + if (!qt_androidRequestCameraPermission()) + return nullptr; + AndroidCameraPrivate *d = new AndroidCameraPrivate(); QThread *worker = new QThread; worker->start(); @@ -764,7 +762,7 @@ QJNIObjectPrivate AndroidCamera::getCameraObject() int AndroidCamera::getNumberOfCameras() { - if (!requestCameraPermission()) + if (!qt_androidRequestCameraPermission()) return 0; return QJNIObjectPrivate::callStaticMethod("android/hardware/Camera", @@ -801,11 +799,6 @@ void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) } } -bool AndroidCamera::requestCameraPermission() -{ - return qt_androidRequestPermission(cameraPermissionKey()); -} - void AndroidCamera::startPreview() { Q_D(AndroidCamera); -- cgit v1.2.3