summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Wu <peng.wu@intopalo.com>2015-04-22 12:42:38 +0300
committerPengWu <peng.wu@intopalo.com>2015-04-23 07:10:28 +0000
commit61033aa420b4d34107e3cc67e8751506bc4ab745 (patch)
tree8ad4312cf41d31a1d20468644b579a67dc87bd8d
parentd44f5734bf945b9b3d57f2bc9c73243343c21518 (diff)
winrt: fix camera sample queue thread safety
Replace sample buffer QVector with C array to avoid reallocations. The resource needs to be protected, so use atomic indexes to prevent writing into the same array element that is being read. Task-number: QTBUG-45667 Change-Id: Ifd30dd128765ea4794fe8614f25ef596bba891ee Reviewed-by: Andrew Knight <qt@panimo.net> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
-rw-r--r--src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
index 74afabaf3..bcae8a201 100644
--- a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
+++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
@@ -132,11 +132,14 @@ private:
ComPtr<ID3D11VideoProcessorOutputView> m_outputView;
};
+#define CAMERA_SAMPLE_QUEUE_SIZE 5
class QWinRTCameraVideoRendererControlPrivate
{
public:
QScopedPointer<D3DVideoBlitter> blitter;
- QVector<ComPtr<IMF2DBuffer>> buffers;
+ ComPtr<IMF2DBuffer> buffers[CAMERA_SAMPLE_QUEUE_SIZE];
+ QAtomicInteger<quint16> writeIndex;
+ QAtomicInteger<quint16> readIndex;
};
QWinRTCameraVideoRendererControl::QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent)
@@ -153,13 +156,17 @@ bool QWinRTCameraVideoRendererControl::render(ID3D11Texture2D *target)
{
Q_D(QWinRTCameraVideoRendererControl);
- if (d->buffers.isEmpty()) {
+ const quint16 readIndex = d->readIndex;
+ if (readIndex == d->writeIndex) {
emit bufferRequested();
return false;
}
HRESULT hr;
- ComPtr<IMF2DBuffer> buffer = d->buffers.takeFirst();
+ ComPtr<IMF2DBuffer> buffer = d->buffers[readIndex];
+ Q_ASSERT(buffer);
+ d->buffers[readIndex].Reset();
+ d->readIndex = (readIndex + 1) % CAMERA_SAMPLE_QUEUE_SIZE;
ComPtr<ID3D11Texture2D> sourceTexture;
ComPtr<IMFDXGIBuffer> dxgiBuffer;
@@ -186,11 +193,17 @@ void QWinRTCameraVideoRendererControl::queueBuffer(IMF2DBuffer *buffer)
{
Q_D(QWinRTCameraVideoRendererControl);
Q_ASSERT(buffer);
- d->buffers.append(buffer);
+ const quint16 writeIndex = (d->writeIndex + 1) % CAMERA_SAMPLE_QUEUE_SIZE;
+ if (d->readIndex == writeIndex) // Drop new sample if queue is full
+ return;
+ d->buffers[d->writeIndex] = buffer;
+ d->writeIndex = writeIndex;
}
void QWinRTCameraVideoRendererControl::discardBuffers()
{
Q_D(QWinRTCameraVideoRendererControl);
- d->buffers.clear();
+ d->writeIndex = d->readIndex = 0;
+ for (ComPtr<IMF2DBuffer> &buffer : d->buffers)
+ buffer.Reset();
}