mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
wasapi2ringbuffer: Don't use GLib's weak pointer implementation
GWeakRef takes global mutex. Use C++ weak_ptr which will perform atomic operation internally. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5176>
This commit is contained in:
parent
815b1dfb4a
commit
c992dd2184
1 changed files with 36 additions and 16 deletions
|
@ -21,6 +21,7 @@
|
|||
#include <string.h>
|
||||
#include <mfapi.h>
|
||||
#include <wrl.h>
|
||||
#include <memory>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_wasapi2_ring_buffer_debug);
|
||||
#define GST_CAT_DEFAULT gst_wasapi2_ring_buffer_debug
|
||||
|
@ -32,22 +33,28 @@ gst_wasapi2_ring_buffer_loopback_callback (GstWasapi2RingBuffer * buf);
|
|||
/* *INDENT-OFF* */
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
struct GstWasapi2RingBufferPtr
|
||||
{
|
||||
GstWasapi2RingBufferPtr (GstWasapi2RingBuffer * ringbuffer)
|
||||
: obj(ringbuffer)
|
||||
{
|
||||
}
|
||||
|
||||
/* Point to ringbuffer without holding ownership */
|
||||
GstWasapi2RingBuffer *obj;
|
||||
};
|
||||
|
||||
class GstWasapiAsyncCallback : public IMFAsyncCallback
|
||||
{
|
||||
public:
|
||||
GstWasapiAsyncCallback(GstWasapi2RingBuffer *listener,
|
||||
GstWasapiAsyncCallback(std::shared_ptr<GstWasapi2RingBufferPtr> listener,
|
||||
DWORD queue_id,
|
||||
gboolean loopback)
|
||||
: ref_count_(1)
|
||||
, queue_id_(queue_id)
|
||||
, listener_(listener)
|
||||
, loopback_(loopback)
|
||||
{
|
||||
g_weak_ref_init (&listener_, listener);
|
||||
}
|
||||
|
||||
virtual ~GstWasapiAsyncCallback ()
|
||||
{
|
||||
g_weak_ref_set (&listener_, nullptr);
|
||||
}
|
||||
|
||||
/* IUnknown */
|
||||
|
@ -108,20 +115,18 @@ public:
|
|||
STDMETHODIMP
|
||||
Invoke(IMFAsyncResult * pAsyncResult)
|
||||
{
|
||||
GstWasapi2RingBuffer *ringbuffer;
|
||||
HRESULT hr;
|
||||
auto ptr = listener_.lock ();
|
||||
|
||||
ringbuffer = (GstWasapi2RingBuffer *) g_weak_ref_get (&listener_);
|
||||
if (!ringbuffer) {
|
||||
if (!ptr) {
|
||||
GST_WARNING ("Listener was removed");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (loopback_)
|
||||
hr = gst_wasapi2_ring_buffer_loopback_callback (ringbuffer);
|
||||
hr = gst_wasapi2_ring_buffer_loopback_callback (ptr->obj);
|
||||
else
|
||||
hr = gst_wasapi2_ring_buffer_io_callback (ringbuffer);
|
||||
gst_object_unref (ringbuffer);
|
||||
hr = gst_wasapi2_ring_buffer_io_callback (ptr->obj);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -129,9 +134,14 @@ public:
|
|||
private:
|
||||
ULONG ref_count_;
|
||||
DWORD queue_id_;
|
||||
GWeakRef listener_;
|
||||
std::weak_ptr<GstWasapi2RingBufferPtr> listener_;
|
||||
gboolean loopback_;
|
||||
};
|
||||
|
||||
struct GstWasapi2RingBufferPrivate
|
||||
{
|
||||
std::shared_ptr<GstWasapi2RingBufferPtr> obj_ptr;
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
struct _GstWasapi2RingBuffer
|
||||
|
@ -179,6 +189,8 @@ struct _GstWasapi2RingBuffer
|
|||
gboolean monitor_device_mute;
|
||||
|
||||
GstCaps *supported_caps;
|
||||
|
||||
GstWasapi2RingBufferPrivate *priv;
|
||||
};
|
||||
|
||||
static void gst_wasapi2_ring_buffer_constructed (GObject * object);
|
||||
|
@ -239,6 +251,9 @@ gst_wasapi2_ring_buffer_init (GstWasapi2RingBuffer * self)
|
|||
self->event_handle = CreateEvent (nullptr, FALSE, FALSE, nullptr);
|
||||
self->loopback_event_handle = CreateEvent (nullptr, FALSE, FALSE, nullptr);
|
||||
g_mutex_init (&self->volume_lock);
|
||||
|
||||
self->priv = new GstWasapi2RingBufferPrivate ();
|
||||
self->priv->obj_ptr = std::make_shared < GstWasapi2RingBufferPtr > (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -255,7 +270,8 @@ gst_wasapi2_ring_buffer_constructed (GObject * object)
|
|||
goto out;
|
||||
}
|
||||
|
||||
self->callback_object = new GstWasapiAsyncCallback (self, queue_id, FALSE);
|
||||
self->callback_object = new GstWasapiAsyncCallback (self->priv->obj_ptr,
|
||||
queue_id, FALSE);
|
||||
hr = MFCreateAsyncResult (nullptr, self->callback_object, nullptr,
|
||||
&self->callback_result);
|
||||
if (!gst_wasapi2_result (hr)) {
|
||||
|
@ -265,7 +281,7 @@ gst_wasapi2_ring_buffer_constructed (GObject * object)
|
|||
|
||||
/* Create another callback object for loopback silence feed */
|
||||
self->loopback_callback_object =
|
||||
new GstWasapiAsyncCallback (self, queue_id, TRUE);
|
||||
new GstWasapiAsyncCallback (self->priv->obj_ptr, queue_id, TRUE);
|
||||
hr = MFCreateAsyncResult (nullptr, self->loopback_callback_object, nullptr,
|
||||
&self->loopback_callback_result);
|
||||
if (!gst_wasapi2_result (hr)) {
|
||||
|
@ -284,6 +300,8 @@ gst_wasapi2_ring_buffer_dispose (GObject * object)
|
|||
{
|
||||
GstWasapi2RingBuffer *self = GST_WASAPI2_RING_BUFFER (object);
|
||||
|
||||
self->priv->obj_ptr = nullptr;
|
||||
|
||||
GST_WASAPI2_CLEAR_COM (self->render_client);
|
||||
GST_WASAPI2_CLEAR_COM (self->capture_client);
|
||||
GST_WASAPI2_CLEAR_COM (self->volume_object);
|
||||
|
@ -309,6 +327,8 @@ gst_wasapi2_ring_buffer_finalize (GObject * object)
|
|||
CloseHandle (self->loopback_event_handle);
|
||||
g_mutex_clear (&self->volume_lock);
|
||||
|
||||
delete self->priv;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue