summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow/dsserviceplugin.cpp
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2019-08-30 12:59:29 +0200
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-09-09 12:33:18 +0200
commitcb06ede8ba9a33adbbfdc690faa1a83be4e70b55 (patch)
tree2c3da763347405210683bbb860726214d69a8714 /src/plugins/directshow/dsserviceplugin.cpp
parent97177277a2fcca974d7599ab8ea12ad80ab30efc (diff)
DirectShow: Allow QMediaPlayer in secondary thread
Since using of any COM objects must be only after CoInitialize(), otherwise CoCreateInstance() returns nothing which causes a crash. If QMediaPlayer is moved to another thread, loading of any content will also cause a crash because of COM is not initialized. Proposing to use thread_local ref counter to keep each thread initialized and avoid double initialization. Fixes: QTBUG-77163 Change-Id: I81c67d6407b853c824edd3b42454fddf792fd90c Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/plugins/directshow/dsserviceplugin.cpp')
-rw-r--r--src/plugins/directshow/dsserviceplugin.cpp32
1 files changed, 10 insertions, 22 deletions
diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp
index f92e37c00..cc25e35b7 100644
--- a/src/plugins/directshow/dsserviceplugin.cpp
+++ b/src/plugins/directshow/dsserviceplugin.cpp
@@ -54,6 +54,7 @@
#include "directshowplayerservice.h"
#include <qmediaserviceproviderplugin.h>
+#include "directshowutils.h"
extern const CLSID CLSID_VideoInputDeviceCategory;
@@ -74,28 +75,15 @@ extern const CLSID CLSID_VideoInputDeviceCategory;
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qtDirectShowPlugin, "qt.multimedia.plugins.directshow")
-static int g_refCount = 0;
-void addRefCount()
-{
- if (++g_refCount == 1)
- CoInitialize(nullptr);
-}
-
-void releaseRefCount()
-{
- if (--g_refCount == 0)
- CoUninitialize();
-}
-
QMediaService* DSServicePlugin::create(QString const& key)
{
if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) {
- addRefCount();
+ DirectShowUtils::CoInitializeIfNeeded();
return new DSCameraService;
}
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) {
- addRefCount();
+ DirectShowUtils::CoInitializeIfNeeded();
return new DirectShowPlayerService;
}
@@ -105,7 +93,7 @@ QMediaService* DSServicePlugin::create(QString const& key)
void DSServicePlugin::release(QMediaService *service)
{
delete service;
- releaseRefCount();
+ DirectShowUtils::CoUninitializeIfNeeded();
}
QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
@@ -119,9 +107,9 @@ QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
- addRefCount();
+ DirectShowUtils::CoInitializeIfNeeded();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
- releaseRefCount();
+ DirectShowUtils::CoUninitializeIfNeeded();
if (!devs.isEmpty())
return devs.first().first;
}
@@ -133,9 +121,9 @@ QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
QList<QByteArray> result;
if (service == Q_MEDIASERVICE_CAMERA) {
- addRefCount();
+ DirectShowUtils::CoInitializeIfNeeded();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
- releaseRefCount();
+ DirectShowUtils::CoUninitializeIfNeeded();
for (const DSVideoDeviceInfo &info : devs)
result.append(info.first);
}
@@ -146,9 +134,9 @@ QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
{
if (service == Q_MEDIASERVICE_CAMERA) {
- addRefCount();
+ DirectShowUtils::CoInitializeIfNeeded();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
- releaseRefCount();
+ DirectShowUtils::CoUninitializeIfNeeded();
for (const DSVideoDeviceInfo &info : devs) {
if (info.first == device)
return info.second;