mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +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 <string.h>
|
||||||
#include <mfapi.h>
|
#include <mfapi.h>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_wasapi2_ring_buffer_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_wasapi2_ring_buffer_debug);
|
||||||
#define GST_CAT_DEFAULT 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* */
|
/* *INDENT-OFF* */
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
struct GstWasapi2RingBufferPtr
|
||||||
|
{
|
||||||
|
GstWasapi2RingBufferPtr (GstWasapi2RingBuffer * ringbuffer)
|
||||||
|
: obj(ringbuffer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Point to ringbuffer without holding ownership */
|
||||||
|
GstWasapi2RingBuffer *obj;
|
||||||
|
};
|
||||||
|
|
||||||
class GstWasapiAsyncCallback : public IMFAsyncCallback
|
class GstWasapiAsyncCallback : public IMFAsyncCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GstWasapiAsyncCallback(GstWasapi2RingBuffer *listener,
|
GstWasapiAsyncCallback(std::shared_ptr<GstWasapi2RingBufferPtr> listener,
|
||||||
DWORD queue_id,
|
DWORD queue_id,
|
||||||
gboolean loopback)
|
gboolean loopback)
|
||||||
: ref_count_(1)
|
: ref_count_(1)
|
||||||
, queue_id_(queue_id)
|
, queue_id_(queue_id)
|
||||||
|
, listener_(listener)
|
||||||
, loopback_(loopback)
|
, loopback_(loopback)
|
||||||
{
|
{
|
||||||
g_weak_ref_init (&listener_, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~GstWasapiAsyncCallback ()
|
|
||||||
{
|
|
||||||
g_weak_ref_set (&listener_, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
|
@ -108,20 +115,18 @@ public:
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
Invoke(IMFAsyncResult * pAsyncResult)
|
Invoke(IMFAsyncResult * pAsyncResult)
|
||||||
{
|
{
|
||||||
GstWasapi2RingBuffer *ringbuffer;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
auto ptr = listener_.lock ();
|
||||||
|
|
||||||
ringbuffer = (GstWasapi2RingBuffer *) g_weak_ref_get (&listener_);
|
if (!ptr) {
|
||||||
if (!ringbuffer) {
|
|
||||||
GST_WARNING ("Listener was removed");
|
GST_WARNING ("Listener was removed");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loopback_)
|
if (loopback_)
|
||||||
hr = gst_wasapi2_ring_buffer_loopback_callback (ringbuffer);
|
hr = gst_wasapi2_ring_buffer_loopback_callback (ptr->obj);
|
||||||
else
|
else
|
||||||
hr = gst_wasapi2_ring_buffer_io_callback (ringbuffer);
|
hr = gst_wasapi2_ring_buffer_io_callback (ptr->obj);
|
||||||
gst_object_unref (ringbuffer);
|
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -129,9 +134,14 @@ public:
|
||||||
private:
|
private:
|
||||||
ULONG ref_count_;
|
ULONG ref_count_;
|
||||||
DWORD queue_id_;
|
DWORD queue_id_;
|
||||||
GWeakRef listener_;
|
std::weak_ptr<GstWasapi2RingBufferPtr> listener_;
|
||||||
gboolean loopback_;
|
gboolean loopback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GstWasapi2RingBufferPrivate
|
||||||
|
{
|
||||||
|
std::shared_ptr<GstWasapi2RingBufferPtr> obj_ptr;
|
||||||
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
struct _GstWasapi2RingBuffer
|
struct _GstWasapi2RingBuffer
|
||||||
|
@ -179,6 +189,8 @@ struct _GstWasapi2RingBuffer
|
||||||
gboolean monitor_device_mute;
|
gboolean monitor_device_mute;
|
||||||
|
|
||||||
GstCaps *supported_caps;
|
GstCaps *supported_caps;
|
||||||
|
|
||||||
|
GstWasapi2RingBufferPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gst_wasapi2_ring_buffer_constructed (GObject * object);
|
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->event_handle = CreateEvent (nullptr, FALSE, FALSE, nullptr);
|
||||||
self->loopback_event_handle = CreateEvent (nullptr, FALSE, FALSE, nullptr);
|
self->loopback_event_handle = CreateEvent (nullptr, FALSE, FALSE, nullptr);
|
||||||
g_mutex_init (&self->volume_lock);
|
g_mutex_init (&self->volume_lock);
|
||||||
|
|
||||||
|
self->priv = new GstWasapi2RingBufferPrivate ();
|
||||||
|
self->priv->obj_ptr = std::make_shared < GstWasapi2RingBufferPtr > (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -255,7 +270,8 @@ gst_wasapi2_ring_buffer_constructed (GObject * object)
|
||||||
goto out;
|
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,
|
hr = MFCreateAsyncResult (nullptr, self->callback_object, nullptr,
|
||||||
&self->callback_result);
|
&self->callback_result);
|
||||||
if (!gst_wasapi2_result (hr)) {
|
if (!gst_wasapi2_result (hr)) {
|
||||||
|
@ -265,7 +281,7 @@ gst_wasapi2_ring_buffer_constructed (GObject * object)
|
||||||
|
|
||||||
/* Create another callback object for loopback silence feed */
|
/* Create another callback object for loopback silence feed */
|
||||||
self->loopback_callback_object =
|
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,
|
hr = MFCreateAsyncResult (nullptr, self->loopback_callback_object, nullptr,
|
||||||
&self->loopback_callback_result);
|
&self->loopback_callback_result);
|
||||||
if (!gst_wasapi2_result (hr)) {
|
if (!gst_wasapi2_result (hr)) {
|
||||||
|
@ -284,6 +300,8 @@ gst_wasapi2_ring_buffer_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
GstWasapi2RingBuffer *self = GST_WASAPI2_RING_BUFFER (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->render_client);
|
||||||
GST_WASAPI2_CLEAR_COM (self->capture_client);
|
GST_WASAPI2_CLEAR_COM (self->capture_client);
|
||||||
GST_WASAPI2_CLEAR_COM (self->volume_object);
|
GST_WASAPI2_CLEAR_COM (self->volume_object);
|
||||||
|
@ -309,6 +327,8 @@ gst_wasapi2_ring_buffer_finalize (GObject * object)
|
||||||
CloseHandle (self->loopback_event_handle);
|
CloseHandle (self->loopback_event_handle);
|
||||||
g_mutex_clear (&self->volume_lock);
|
g_mutex_clear (&self->volume_lock);
|
||||||
|
|
||||||
|
delete self->priv;
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue