Skip to content

Commit

Permalink
🐛 [Windows] Fix: if an exception is thrown in the constructor make su…
Browse files Browse the repository at this point in the history
…re we properly cleanup

Because the destructor won't get called, but we have already init some of our members and they need to be cleaned up
  • Loading branch information
JulesFouchy committed Oct 21, 2024
1 parent c08cde4 commit 0c7af1a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
9 changes: 6 additions & 3 deletions src/internal/wcam_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,13 @@ STDMETHODIMP CaptureImpl::BufferCB(double /* time */, BYTE* buffer, long buffer_
return S_OK;
}

CaptureImpl::~CaptureImpl()
MediaControlRAII::~MediaControlRAII()
{
_media_control->Stop();
_media_control->Release();
if (_media_control)
{
_media_control->Stop();
_media_control->Release();
}
}

static auto get_resolutions(IBaseFilter* capture_filter) -> std::vector<Resolution>
Expand Down
29 changes: 26 additions & 3 deletions src/internal/wcam_windows.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,35 @@

namespace wcam::internal {

class MediaControlRAII {
public:
MediaControlRAII() = default;
~MediaControlRAII();
MediaControlRAII(MediaControlRAII const&) = delete;
MediaControlRAII& operator=(MediaControlRAII const&) = delete;
MediaControlRAII(MediaControlRAII&&) noexcept = delete;
MediaControlRAII& operator=(MediaControlRAII&&) noexcept = delete;

auto operator->() -> IMediaControl* { return _media_control; }
auto operator->() const -> IMediaControl const* { return _media_control; }
auto operator*() -> IMediaControl& { return *_media_control; }
auto operator*() const -> IMediaControl const& { return *_media_control; }
operator IMediaControl*() { return _media_control; } // NOLINT(*explicit*)
IMediaControl** operator&() // NOLINT(*runtime-operator)
{
return &_media_control;
}

private:
IMediaControl* _media_control{};
};

EXTERN_C const IID IID_ISampleGrabberCB;
class CaptureImpl : public ISampleGrabberCB
, public ICaptureImpl {
public:
CaptureImpl(DeviceId const& id, Resolution const& resolution);
~CaptureImpl() override;
~CaptureImpl() override = default;
CaptureImpl(CaptureImpl const&) = delete;
auto operator=(CaptureImpl const&) -> CaptureImpl& = delete;
CaptureImpl(CaptureImpl&&) noexcept = delete;
Expand All @@ -32,8 +55,8 @@ class CaptureImpl : public ISampleGrabberCB
Resolution _resolution{};
GUID _video_format{}; // At the moment we support MEDIASUBTYPE_RGB24 and MEDIASUBTYPE_NV12 (which is required for the OBS virtual camera)

IMediaControl* _media_control{};
ULONG _ref_count{0};
MediaControlRAII _media_control{};
ULONG _ref_count{0};
};

} // namespace wcam::internal
Expand Down

0 comments on commit 0c7af1a

Please sign in to comment.