mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-14 23:34:08 +00:00
virtualcam-module: Stop thread on Stop call
This causes the thread to only start when the IMediaFilter::Run/Pause calls have been made, and stop whenever either the IMediaFilter::Stop call has been made, or on destruction, whichever comes first. This potentially will work around a suspected race condition that appears to be in the WebRTC library where the filter's library will be released while the filter is in the process of being destroyed, which can take longer than usual if the join takes too long. Basically, fixes a reported crash (that doesn't appear to technically be our fault) when the filter is used with browsers when the virtualcam is deactivating in web browsers.
This commit is contained in:
parent
139e6ed69e
commit
865eecb739
|
@ -45,6 +45,17 @@ VCamFilter::VCamFilter()
|
|||
|
||||
in_obs = !!wcsstr(file, obs_process);
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
AddRef();
|
||||
}
|
||||
|
||||
inline void VCamFilter::ActuallyStart()
|
||||
{
|
||||
if (th.joinable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
/* add last/current obs res/interval */
|
||||
|
||||
|
@ -103,21 +114,32 @@ VCamFilter::VCamFilter()
|
|||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
/* Actually start */
|
||||
|
||||
ResetEvent(thread_stop);
|
||||
th = std::thread([this] { Thread(); });
|
||||
SetEvent(thread_start);
|
||||
}
|
||||
|
||||
AddRef();
|
||||
inline void VCamFilter::ActuallyStop()
|
||||
{
|
||||
if (!th.joinable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetEvent(thread_stop);
|
||||
th.join();
|
||||
video_queue_close(vq);
|
||||
|
||||
if (placeholder.scaled_data) {
|
||||
free(placeholder.scaled_data);
|
||||
placeholder.scaled_data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
VCamFilter::~VCamFilter()
|
||||
{
|
||||
SetEvent(thread_stop);
|
||||
if (th.joinable())
|
||||
th.join();
|
||||
video_queue_close(vq);
|
||||
|
||||
if (placeholder.scaled_data)
|
||||
free(placeholder.scaled_data);
|
||||
ActuallyStop();
|
||||
}
|
||||
|
||||
const wchar_t *VCamFilter::FilterName() const
|
||||
|
@ -134,7 +156,29 @@ STDMETHODIMP VCamFilter::Pause()
|
|||
return hr;
|
||||
}
|
||||
|
||||
SetEvent(thread_start);
|
||||
ActuallyStart();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP VCamFilter::Run(REFERENCE_TIME tStart)
|
||||
{
|
||||
HRESULT hr = OutputFilter::Run(tStart);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
ActuallyStart();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP VCamFilter::Stop()
|
||||
{
|
||||
HRESULT hr = OutputFilter::Stop();
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
ActuallyStop();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ class VCamFilter : public DShow::OutputFilter {
|
|||
void UpdatePlaceholder(void);
|
||||
const int GetOutputBufferSize(void);
|
||||
|
||||
inline void ActuallyStart();
|
||||
inline void ActuallyStop();
|
||||
|
||||
protected:
|
||||
const wchar_t *FilterName() const override;
|
||||
|
||||
|
@ -60,4 +63,6 @@ public:
|
|||
~VCamFilter() override;
|
||||
|
||||
STDMETHODIMP Pause() override;
|
||||
STDMETHODIMP Stop() override;
|
||||
STDMETHODIMP Run(REFERENCE_TIME tStart) override;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue