diff options
author | Andy Shaw <andy.shaw@qt.io> | 2017-08-16 11:33:25 +0200 |
---|---|---|
committer | Andy Shaw <andy.shaw@qt.io> | 2017-08-16 11:58:54 +0000 |
commit | 343e281f0e7cc7fd9e1558e4d92f5019fa565181 (patch) | |
tree | 9262c3bcd119bd582e89f879d33b49acb43787f5 /src | |
parent | 116cd7bdbd1e148aef05c27602780d65be335205 (diff) | |
download | qtmultimedia-343e281f0e7cc7fd9e1558e4d92f5019fa565181.tar.gz |
DirectShow: Copy the frame data when we get it before emitting
Since the slot connected to the frameAvailable signal may be in another
thread there is a bigger risk of it being invalid by the time the slot
is invoked. Therefore we copy the data and emit with the copy to ensure
that we don't lose the data.
Task-number: QTBUG-61817
Change-Id: I2888661d8a7f97105a85f87b08cc9ec25f8ce8c7
Reviewed-by: Christian Stromme <christian.stromme@qt.io>
Diffstat (limited to 'src')
6 files changed, 13 insertions, 16 deletions
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 3f1187baa..55ab868ce 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -529,12 +529,10 @@ int DSCameraSession::captureImage(const QString &fileName) return m_imageIdCounter; } -void DSCameraSession::onFrameAvailable(double time, quint8 *buffer, long len) +void DSCameraSession::onFrameAvailable(double time, const QByteArray &data) { // !!! Not called on the main thread Q_UNUSED(time); - // Deep copy, the data might be modified or freed after the callback returns - QByteArray data(reinterpret_cast<const char *>(buffer), len); m_presentMutex.lock(); diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index 6b6cb49b2..90407f49e 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -156,7 +156,7 @@ private: void setStatus(QCamera::Status status); - void onFrameAvailable(double time, quint8 *buffer, long len); + void onFrameAvailable(double time, const QByteArray &data); void saveCapturedImage(int id, const QImage &image, const QString &path); bool createFilterGraph(); diff --git a/src/plugins/directshow/common/directshowsamplegrabber.cpp b/src/plugins/directshow/common/directshowsamplegrabber.cpp index b33c3cfc6..fb95370ca 100644 --- a/src/plugins/directshow/common/directshowsamplegrabber.cpp +++ b/src/plugins/directshow/common/directshowsamplegrabber.cpp @@ -99,9 +99,11 @@ public: STDMETHODIMP BufferCB(double time, BYTE *buffer, long bufferLen) { - if (m_grabber) - Q_EMIT m_grabber->bufferAvailable(time, buffer, bufferLen); - + if (m_grabber) { + // Deep copy, the data might be modified or freed after the callback returns + QByteArray data(reinterpret_cast<const char *>(buffer), bufferLen); + Q_EMIT m_grabber->bufferAvailable(time, data); + } return S_OK; } diff --git a/src/plugins/directshow/common/directshowsamplegrabber.h b/src/plugins/directshow/common/directshowsamplegrabber.h index edabae2db..a9b72fcd1 100644 --- a/src/plugins/directshow/common/directshowsamplegrabber.h +++ b/src/plugins/directshow/common/directshowsamplegrabber.h @@ -75,7 +75,7 @@ public: Q_SIGNALS: void sampleAvailable(double time, IMediaSample *sample); - void bufferAvailable(double time, quint8 *buffer, long len); + void bufferAvailable(double time, const QByteArray &data); private: IBaseFilter *m_filter; diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 2f959b232..9cbb62969 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -1453,7 +1453,7 @@ void DirectShowPlayerService::videoOutputChanged() QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") -void DirectShowPlayerService::onAudioBufferAvailable(double time, quint8 *buffer, long len) +void DirectShowPlayerService::onAudioBufferAvailable(double time, const QByteArray &data) { QMutexLocker locker(&m_mutex); if (!m_audioProbeControl || !m_audioSampleGrabber) @@ -1497,18 +1497,16 @@ void DirectShowPlayerService::onAudioBufferAvailable(double time, quint8 *buffer format.setSampleType(QAudioFormat::SignedInt); const quint64 startTime = quint64(time * 1000.); - QAudioBuffer audioBuffer(QByteArray(reinterpret_cast<const char *>(buffer), len), + QAudioBuffer audioBuffer(data, format, startTime); Q_EMIT m_audioProbeControl->audioBufferProbed(audioBuffer); } -void DirectShowPlayerService::onVideoBufferAvailable(double time, quint8 *buffer, long len) +void DirectShowPlayerService::onVideoBufferAvailable(double time, const QByteArray &data) { Q_UNUSED(time); - Q_UNUSED(buffer); - Q_UNUSED(len); QMutexLocker locker(&m_mutex); if (!m_videoProbeControl || !m_videoSampleGrabber) @@ -1536,7 +1534,6 @@ void DirectShowPlayerService::onVideoBufferAvailable(double time, quint8 *buffer const QSize &size = videoFormat.frameSize(); const int bytesPerLine = DirectShowMediaType::bytesPerLine(videoFormat); - QByteArray data(reinterpret_cast<const char *>(buffer), len); QVideoFrame frame(new QMemoryVideoBuffer(data, bytesPerLine), size, format); diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index 676d88fb5..01d05449e 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -106,8 +106,8 @@ protected: private Q_SLOTS: void videoOutputChanged(); - void onAudioBufferAvailable(double time, quint8 *buffer, long len); - void onVideoBufferAvailable(double time, quint8 *buffer, long len); + void onAudioBufferAvailable(double time, const QByteArray &data); + void onVideoBufferAvailable(double time, const QByteArray &data); private: void releaseGraph(); |