mediafoundation: Refactor GstMFSourceObject implementation

* Move CoInitializeEx/CoUninitialize pair into thread function in order to
  ensure MTA COM thread
* Move common code to baseclass

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1269>
This commit is contained in:
Seungha Yang 2020-05-14 20:47:06 +09:00 committed by GStreamer Merge Bot
parent c29c71ae9d
commit 8afc283b51
4 changed files with 276 additions and 190 deletions

View file

@ -241,11 +241,13 @@ struct _GstMFCaptureEngine
gboolean flushing;
};
static void gst_mf_capture_engine_constructed (GObject * object);
static void gst_mf_capture_engine_finalize (GObject * object);
static gboolean gst_mf_capture_engine_open (GstMFSourceObject * object,
IMFActivate * activate);
static gboolean gst_mf_capture_engine_start (GstMFSourceObject * object);
static gboolean gst_mf_capture_engine_stop (GstMFSourceObject * object);
static gboolean gst_mf_capture_engine_close (GstMFSourceObject * object);
static GstFlowReturn gst_mf_capture_engine_fill (GstMFSourceObject * object,
GstBuffer * buffer);
static gboolean gst_mf_capture_engine_unlock (GstMFSourceObject * object);
@ -264,11 +266,12 @@ gst_mf_capture_engine_class_init (GstMFCaptureEngineClass * klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstMFSourceObjectClass *source_class = GST_MF_SOURCE_OBJECT_CLASS (klass);
gobject_class->constructed = gst_mf_capture_engine_constructed;
gobject_class->finalize = gst_mf_capture_engine_finalize;
source_class->open = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_open);
source_class->start = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_start);
source_class->stop = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_stop);
source_class->close = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_close);
source_class->fill = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_fill);
source_class->unlock = GST_DEBUG_FUNCPTR (gst_mf_capture_engine_unlock);
source_class->unlock_stop =
@ -283,8 +286,6 @@ gst_mf_capture_engine_init (GstMFCaptureEngine * self)
self->queue = g_queue_new ();
g_mutex_init (&self->lock);
g_cond_init (&self->cond);
CoInitializeEx (NULL, COINIT_MULTITHREADED);
}
static gboolean
@ -373,9 +374,10 @@ gst_mf_stream_media_type_free (GstMFStreamMediaType * media_type)
}
static gboolean
gst_mf_capture_engine_create (GstMFCaptureEngine * self,
gst_mf_capture_engine_open (GstMFSourceObject * object,
IMFActivate * activate)
{
GstMFCaptureEngine *self = GST_MF_CAPTURE_ENGINE (object);
GList *iter;
ComPtr<IMFCaptureEngineClassFactory> factory;
ComPtr<IMFCaptureEngine> engine;
@ -469,63 +471,36 @@ gst_mf_capture_engine_create (GstMFCaptureEngine * self,
return TRUE;
}
static void
gst_mf_capture_engine_constructed (GObject * object)
static gboolean
gst_mf_capture_engine_close (GstMFSourceObject * object)
{
GstMFSourceObject *source = GST_MF_SOURCE_OBJECT (object);
GstMFCaptureEngine *self = GST_MF_CAPTURE_ENGINE (object);
GList *activate_list = NULL;
GstMFDeviceActivate *target = NULL;
GList *iter;
if (!gst_mf_source_enum_device_activate (source->soure_type, &activate_list)) {
GST_WARNING_OBJECT (self, "No available video capture device");
return;
}
#ifndef GST_DISABLE_GST_DEBUG
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
gst_clear_caps (&self->supported_caps);
GST_DEBUG_OBJECT (self, "device %d, name: \"%s\", path: \"%s\"",
activate->index, GST_STR_NULL (activate->name),
GST_STR_NULL (activate->path));
}
#endif
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
gboolean match;
if (source->device_path && strlen (source->device_path) > 0) {
match = g_ascii_strcasecmp (activate->path, source->device_path) == 0;
} else if (source->device_name && strlen (source->device_name) > 0) {
match = g_ascii_strcasecmp (activate->name, source->device_name) == 0;
} else if (source->device_index >= 0) {
match = activate->index == source->device_index;
} else {
/* pick the first entry */
match = TRUE;
}
if (match) {
target = activate;
break;
}
if (self->media_types) {
g_list_free_full (self->media_types,
(GDestroyNotify) gst_mf_stream_media_type_free);
self->media_types = NULL;
}
if (target)
gst_mf_capture_engine_create (self, target->handle);
if (self->callback_obj) {
self->callback_obj->Release ();
self->callback_obj = NULL;
}
if (activate_list)
g_list_free_full (activate_list,
(GDestroyNotify) gst_mf_device_activate_free);
}
if (self->engine) {
self->engine->Release ();
self->engine = NULL;
}
static void
release_mf_buffer (IMFMediaBuffer * buffer)
{
if (buffer)
buffer->Release ();
if (self->source) {
self->source->Shutdown ();
self->source->Release ();
self->source = NULL;
}
return TRUE;
}
static void
@ -533,32 +508,10 @@ gst_mf_capture_engine_finalize (GObject * object)
{
GstMFCaptureEngine *self = GST_MF_CAPTURE_ENGINE (object);
gst_clear_caps (&self->supported_caps);
if (self->media_types)
g_list_free_full (self->media_types,
(GDestroyNotify) gst_mf_stream_media_type_free);
gst_mf_capture_engine_stop (GST_MF_SOURCE_OBJECT (self));
g_queue_free_full (self->queue, (GDestroyNotify) release_mf_buffer);
if (self->callback_obj) {
self->callback_obj->Release ();
}
if (self->engine)
self->engine->Release ();
if (self->source) {
self->source->Shutdown ();
self->source->Release ();
}
g_queue_free (self->queue);
g_mutex_clear (&self->lock);
g_cond_clear (&self->cond);
CoUninitialize ();
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -712,6 +665,11 @@ gst_mf_capture_engine_stop (GstMFSourceObject * object)
}
}
while (!g_queue_is_empty (self->queue)) {
IMFMediaBuffer *buffer = (IMFMediaBuffer *) g_queue_pop_head (self->queue);
buffer->Release ();
}
return TRUE;
}
@ -866,7 +824,7 @@ GstMFSourceObject *
gst_mf_capture_engine_new (GstMFSourceType type, gint device_index,
const gchar * device_name, const gchar * device_path)
{
GstMFCaptureEngine *self;
GstMFSourceObject *self;
gchar *name;
gchar *path;
@ -876,7 +834,7 @@ gst_mf_capture_engine_new (GstMFSourceType type, gint device_index,
name = device_name ? g_strdup (device_name) : g_strdup ("");
path = device_path ? g_strdup (device_path) : g_strdup ("");
self = (GstMFCaptureEngine *) g_object_new (GST_TYPE_MF_CAPTURE_ENGINE,
self = (GstMFSourceObject *) g_object_new (GST_TYPE_MF_CAPTURE_ENGINE,
"source-type", type, "device-index", device_index, "device-name", name,
"device-path", path, NULL);
@ -884,10 +842,11 @@ gst_mf_capture_engine_new (GstMFSourceType type, gint device_index,
g_free (name);
g_free (path);
if (!self->source) {
gst_clear_object (&self);
if (!self->opend) {
GST_WARNING_OBJECT (self, "Couldn't open device");
gst_object_unref (self);
return NULL;
}
return GST_MF_SOURCE_OBJECT (self);
return self;
}

View file

@ -58,14 +58,36 @@ gst_mf_source_type_get_type (void)
return source_type;
}
struct _GstMFSourceObjectPrivate
{
GstMFSourceType soure_type;
gchar *device_path;
gchar *device_name;
gint device_index;
GThread *thread;
GMutex lock;
GCond cond;
GMainContext *context;
GMainLoop *loop;
};
static void gst_mf_source_object_constructed (GObject * object);
static void gst_mf_source_object_dispose (GObject * object);
static void gst_mf_source_object_finalize (GObject * object);
static void gst_mf_source_object_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_mf_source_object_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static gpointer gst_mf_source_object_thread_func (GstMFSourceObject * self);
static gboolean gst_mf_source_enum_device_activate (GstMFSourceObject * self,
GstMFSourceType source_type, GList ** device_activates);
static void gst_mf_device_activate_free (GstMFDeviceActivate * activate);
#define gst_mf_source_object_parent_class parent_class
G_DEFINE_ABSTRACT_TYPE (GstMFSourceObject, gst_mf_source_object,
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GstMFSourceObject, gst_mf_source_object,
GST_TYPE_OBJECT);
static void
@ -73,6 +95,8 @@ gst_mf_source_object_class_init (GstMFSourceObjectClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructed = gst_mf_source_object_constructed;
gobject_class->dispose = gst_mf_source_object_dispose;
gobject_class->finalize = gst_mf_source_object_finalize;
gobject_class->get_property = gst_mf_source_object_get_property;
gobject_class->set_property = gst_mf_source_object_set_property;
@ -99,17 +123,65 @@ gst_mf_source_object_class_init (GstMFSourceObjectClass * klass)
static void
gst_mf_source_object_init (GstMFSourceObject * self)
{
self->device_index = DEFAULT_DEVICE_INDEX;
self->soure_type = DEFAULT_SOURCE_TYPE;
GstMFSourceObjectPrivate *priv;
self->priv = priv = gst_mf_source_object_get_instance_private (self);
priv->device_index = DEFAULT_DEVICE_INDEX;
priv->soure_type = DEFAULT_SOURCE_TYPE;
g_mutex_init (&priv->lock);
g_cond_init (&priv->cond);
priv->context = g_main_context_new ();
priv->loop = g_main_loop_new (priv->context, FALSE);
}
static void
gst_mf_source_object_constructed (GObject * object)
{
GstMFSourceObject *self = GST_MF_SOURCE_OBJECT (object);
GstMFSourceObjectPrivate *priv = self->priv;
/* Create thread so that ensure COM thread can be MTA thread */
g_mutex_lock (&priv->lock);
priv->thread = g_thread_new ("GstMFSourceObject",
(GThreadFunc) gst_mf_source_object_thread_func, self);
while (!g_main_loop_is_running (priv->loop))
g_cond_wait (&priv->cond, &priv->lock);
g_mutex_unlock (&priv->lock);
G_OBJECT_CLASS (parent_class)->constructed (object);
}
static void
gst_mf_source_object_dispose (GObject * object)
{
GstMFSourceObject *self = GST_MF_SOURCE_OBJECT (object);
GstMFSourceObjectPrivate *priv = self->priv;
if (priv->loop) {
g_main_loop_quit (priv->loop);
g_thread_join (priv->thread);
g_main_loop_unref (priv->loop);
g_main_context_unref (priv->context);
priv->loop = NULL;
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_mf_source_object_finalize (GObject * object)
{
GstMFSourceObject *self = GST_MF_SOURCE_OBJECT (object);
GstMFSourceObjectPrivate *priv = self->priv;
g_free (self->device_path);
g_free (self->device_name);
g_mutex_clear (&priv->lock);
g_cond_clear (&priv->cond);
g_free (priv->device_path);
g_free (priv->device_name);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -119,19 +191,20 @@ gst_mf_source_object_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstMFSourceObject *self = GST_MF_SOURCE_OBJECT (object);
GstMFSourceObjectPrivate *priv = self->priv;
switch (prop_id) {
case PROP_DEVICE_PATH:
g_value_set_string (value, self->device_path);
g_value_set_string (value, priv->device_path);
break;
case PROP_DEVICE_NAME:
g_value_set_string (value, self->device_name);
g_value_set_string (value, priv->device_name);
break;
case PROP_DEVICE_INDEX:
g_value_set_int (value, self->device_index);
g_value_set_int (value, priv->device_index);
break;
case PROP_SOURCE_TYPE:
g_value_set_enum (value, self->soure_type);
g_value_set_enum (value, priv->soure_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -144,21 +217,22 @@ gst_mf_source_object_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstMFSourceObject *self = GST_MF_SOURCE_OBJECT (object);
GstMFSourceObjectPrivate *priv = self->priv;
switch (prop_id) {
case PROP_DEVICE_PATH:
g_free (self->device_path);
self->device_path = g_value_dup_string (value);
g_free (priv->device_path);
priv->device_path = g_value_dup_string (value);
break;
case PROP_DEVICE_NAME:
g_free (self->device_name);
self->device_name = g_value_dup_string (value);
g_free (priv->device_name);
priv->device_name = g_value_dup_string (value);
break;
case PROP_DEVICE_INDEX:
self->device_index = g_value_get_int (value);
priv->device_index = g_value_get_int (value);
break;
case PROP_SOURCE_TYPE:
self->soure_type = g_value_get_enum (value);
priv->soure_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -166,6 +240,101 @@ gst_mf_source_object_set_property (GObject * object, guint prop_id,
}
}
static gboolean
gst_mf_source_object_main_loop_running_cb (GstMFSourceObject * self)
{
GstMFSourceObjectPrivate *priv = self->priv;
GST_TRACE_OBJECT (self, "Main loop running now");
g_mutex_lock (&priv->lock);
g_cond_signal (&priv->cond);
g_mutex_unlock (&priv->lock);
return G_SOURCE_REMOVE;
}
static gpointer
gst_mf_source_object_thread_func (GstMFSourceObject * self)
{
GstMFSourceObjectPrivate *priv = self->priv;
GstMFSourceObjectClass *klass = GST_MF_SOURCE_OBJECT_GET_CLASS (self);
GSource *source;
GList *activate_list = NULL;
GstMFDeviceActivate *target = NULL;
GList *iter;
g_assert (klass->open != NULL);
g_assert (klass->close != NULL);
CoInitializeEx (NULL, COINIT_MULTITHREADED);
g_main_context_push_thread_default (priv->context);
source = g_idle_source_new ();
g_source_set_callback (source,
(GSourceFunc) gst_mf_source_object_main_loop_running_cb, self, NULL);
g_source_attach (source, priv->context);
g_source_unref (source);
if (!gst_mf_source_enum_device_activate (self,
priv->soure_type, &activate_list)) {
GST_WARNING_OBJECT (self, "No available video capture device");
goto run_loop;
}
#ifndef GST_DISABLE_GST_DEBUG
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
GST_DEBUG_OBJECT (self, "device %d, name: \"%s\", path: \"%s\"",
activate->index, GST_STR_NULL (activate->name),
GST_STR_NULL (activate->path));
}
#endif
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
gboolean match;
if (priv->device_path && strlen (priv->device_path) > 0) {
match = g_ascii_strcasecmp (activate->path, priv->device_path) == 0;
} else if (priv->device_name && strlen (priv->device_name) > 0) {
match = g_ascii_strcasecmp (activate->name, priv->device_name) == 0;
} else if (priv->device_index >= 0) {
match = activate->index == priv->device_index;
} else {
/* pick the first entry */
match = TRUE;
}
if (match) {
target = activate;
break;
}
}
if (target)
self->opend = klass->open (self, target->handle);
if (activate_list)
g_list_free_full (activate_list,
(GDestroyNotify) gst_mf_device_activate_free);
run_loop:
GST_TRACE_OBJECT (self, "Starting main loop");
g_main_loop_run (priv->loop);
GST_TRACE_OBJECT (self, "Stopped main loop");
klass->stop (self);
klass->close (self);
g_main_context_pop_thread_default (priv->context);
CoUninitialize ();
return NULL;
}
gboolean
gst_mf_source_object_start (GstMFSourceObject * object)
{
@ -251,9 +420,9 @@ gst_mf_source_object_get_caps (GstMFSourceObject * object)
return klass->get_caps (object);
}
gboolean
gst_mf_source_enum_device_activate (GstMFSourceType source_type,
GList ** device_sources)
static gboolean
gst_mf_source_enum_device_activate (GstMFSourceObject * self,
GstMFSourceType source_type, GList ** device_sources)
{
HRESULT hr;
GList *ret = NULL;
@ -272,7 +441,7 @@ gst_mf_source_enum_device_activate (GstMFSourceType source_type,
&MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
break;
default:
GST_ERROR ("Unknown source type %d", source_type);
GST_ERROR_OBJECT (self, "Unknown source type %d", source_type);
return FALSE;
}
@ -332,7 +501,7 @@ done:
return ! !ret;
}
void
static void
gst_mf_device_activate_free (GstMFDeviceActivate * activate)
{
g_return_if_fail (activate != NULL);

View file

@ -35,6 +35,7 @@ G_BEGIN_DECLS
typedef struct _GstMFSourceObject GstMFSourceObject;
typedef struct _GstMFSourceObjectClass GstMFSourceObjectClass;
typedef struct _GstMFSourceObjectPrivate GstMFSourceObjectPrivate;
typedef enum
{
@ -56,21 +57,24 @@ struct _GstMFSourceObject
{
GstObject parent;
GstMFSourceType soure_type;
gboolean opend;
gchar *device_path;
gchar *device_name;
gint device_index;
GstMFSourceObjectPrivate *priv;
};
struct _GstMFSourceObjectClass
{
GstObjectClass parent_class;
gboolean (*open) (GstMFSourceObject * object,
IMFActivate * activate);
gboolean (*start) (GstMFSourceObject * object);
gboolean (*stop) (GstMFSourceObject * object);
gboolean (*close) (GstMFSourceObject * object);
GstFlowReturn (*fill) (GstMFSourceObject * object,
GstBuffer * buffer);
@ -101,12 +105,6 @@ GstCaps * gst_mf_source_object_get_caps (GstMFSourceObject * object);
gboolean gst_mf_source_object_set_caps (GstMFSourceObject * object,
GstCaps * caps);
/* Utils */
gboolean gst_mf_source_enum_device_activate (GstMFSourceType source_type,
GList ** device_activates);
void gst_mf_device_activate_free (GstMFDeviceActivate * activate);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstMFSourceObject, gst_object_unref)
G_END_DECLS

View file

@ -67,11 +67,13 @@ struct _GstMFSourceReader
gboolean flushing;
};
static void gst_mf_source_reader_constructed (GObject * object);
static void gst_mf_source_reader_finalize (GObject * object);
static gboolean gst_mf_source_reader_open (GstMFSourceObject * object,
IMFActivate * activate);
static gboolean gst_mf_source_reader_start (GstMFSourceObject * object);
static gboolean gst_mf_source_reader_stop (GstMFSourceObject * object);
static gboolean gst_mf_source_reader_close (GstMFSourceObject * object);
static GstFlowReturn gst_mf_source_reader_fill (GstMFSourceObject * object,
GstBuffer * buffer);
static gboolean gst_mf_source_reader_unlock (GstMFSourceObject * object);
@ -90,11 +92,12 @@ gst_mf_source_reader_class_init (GstMFSourceReaderClass * klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstMFSourceObjectClass *source_class = GST_MF_SOURCE_OBJECT_CLASS (klass);
gobject_class->constructed = gst_mf_source_reader_constructed;
gobject_class->finalize = gst_mf_source_reader_finalize;
source_class->open = GST_DEBUG_FUNCPTR (gst_mf_source_reader_open);
source_class->start = GST_DEBUG_FUNCPTR (gst_mf_source_reader_start);
source_class->stop = GST_DEBUG_FUNCPTR (gst_mf_source_reader_stop);
source_class->close = GST_DEBUG_FUNCPTR (gst_mf_source_reader_close);
source_class->fill = GST_DEBUG_FUNCPTR (gst_mf_source_reader_fill);
source_class->unlock = GST_DEBUG_FUNCPTR (gst_mf_source_reader_unlock);
source_class->unlock_stop =
@ -108,8 +111,6 @@ gst_mf_source_reader_init (GstMFSourceReader * self)
{
self->queue = g_queue_new ();
g_mutex_init (&self->lock);
CoInitializeEx (NULL, COINIT_MULTITHREADED);
}
static gboolean
@ -185,8 +186,9 @@ gst_mf_stream_media_type_free (GstMFStreamMediaType * media_type)
}
static gboolean
gst_mf_source_reader_create (GstMFSourceReader * self, IMFActivate * activate)
gst_mf_source_reader_open (GstMFSourceObject * object, IMFActivate * activate)
{
GstMFSourceReader *self = GST_MF_SOURCE_READER (object);
GList *iter;
HRESULT hr;
ComPtr<IMFSourceReader> reader;
@ -235,63 +237,31 @@ gst_mf_source_reader_create (GstMFSourceReader * self, IMFActivate * activate)
return TRUE;
}
static void
gst_mf_source_reader_constructed (GObject * object)
static gboolean
gst_mf_source_reader_close (GstMFSourceObject * object)
{
GstMFSourceObject *source = GST_MF_SOURCE_OBJECT (object);
GstMFSourceReader *self = GST_MF_SOURCE_READER (object);
GList *activate_list = NULL;
GstMFDeviceActivate *target = NULL;
GList *iter;
if (!gst_mf_source_enum_device_activate (source->soure_type, &activate_list)) {
GST_WARNING_OBJECT (self, "No available video capture device");
return;
}
#ifndef GST_DISABLE_GST_DEBUG
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
gst_clear_caps (&self->supported_caps);
GST_DEBUG_OBJECT (self, "device %d, name: \"%s\", path: \"%s\"",
activate->index, GST_STR_NULL (activate->name),
GST_STR_NULL (activate->path));
}
#endif
for (iter = activate_list; iter; iter = g_list_next (iter)) {
GstMFDeviceActivate *activate = (GstMFDeviceActivate *) iter->data;
gboolean match;
if (source->device_path && strlen (source->device_path) > 0) {
match = g_ascii_strcasecmp (activate->path, source->device_path) == 0;
} else if (source->device_name && strlen (source->device_name) > 0) {
match = g_ascii_strcasecmp (activate->name, source->device_name) == 0;
} else if (source->device_index >= 0) {
match = activate->index == source->device_index;
} else {
/* pick the first entry */
match = TRUE;
}
if (match) {
target = activate;
break;
}
if (self->media_types) {
g_list_free_full (self->media_types,
(GDestroyNotify) gst_mf_stream_media_type_free);
self->media_types = NULL;
}
if (target)
gst_mf_source_reader_create (self, target->handle);
if (self->reader) {
self->reader->Release ();
self->reader = NULL;
}
if (activate_list)
g_list_free_full (activate_list,
(GDestroyNotify) gst_mf_device_activate_free);
}
if (self->source) {
self->source->Shutdown ();
self->source->Release ();
self->source = NULL;
}
static void
release_mf_buffer (IMFMediaBuffer * buffer)
{
if (buffer)
buffer->Release ();
return TRUE;
}
static void
@ -299,27 +269,9 @@ gst_mf_source_reader_finalize (GObject * object)
{
GstMFSourceReader *self = GST_MF_SOURCE_READER (object);
gst_clear_caps (&self->supported_caps);
if (self->media_types)
g_list_free_full (self->media_types,
(GDestroyNotify) gst_mf_stream_media_type_free);
gst_mf_source_reader_stop (GST_MF_SOURCE_OBJECT (self));
g_queue_free_full (self->queue, (GDestroyNotify) release_mf_buffer);
if (self->reader)
self->reader->Release ();
if (self->source) {
self->source->Shutdown ();
self->source->Release ();
}
g_queue_free (self->queue);
g_mutex_clear (&self->lock);
CoUninitialize ();
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -357,6 +309,13 @@ gst_mf_source_reader_start (GstMFSourceObject * object)
static gboolean
gst_mf_source_reader_stop (GstMFSourceObject * object)
{
GstMFSourceReader *self = GST_MF_SOURCE_READER (object);
while (!g_queue_is_empty (self->queue)) {
IMFMediaBuffer *buffer = (IMFMediaBuffer *) g_queue_pop_head (self->queue);
buffer->Release ();
}
return TRUE;
}
@ -530,7 +489,7 @@ GstMFSourceObject *
gst_mf_source_reader_new (GstMFSourceType type, gint device_index,
const gchar * device_name, const gchar * device_path)
{
GstMFSourceReader *self;
GstMFSourceObject *self;
gchar *name;
gchar *path;
@ -540,7 +499,7 @@ gst_mf_source_reader_new (GstMFSourceType type, gint device_index,
name = device_name ? g_strdup (device_name) : g_strdup ("");
path = device_path ? g_strdup (device_path) : g_strdup ("");
self = (GstMFSourceReader *) g_object_new (GST_TYPE_MF_SOURCE_READER,
self = (GstMFSourceObject *) g_object_new (GST_TYPE_MF_SOURCE_READER,
"source-type", type, "device-index", device_index, "device-name", name,
"device-path", path, NULL);
@ -548,10 +507,11 @@ gst_mf_source_reader_new (GstMFSourceType type, gint device_index,
g_free (name);
g_free (path);
if (!self->source) {
gst_clear_object (&self);
if (!self->opend) {
GST_WARNING_OBJECT (self, "Couldn't open device");
gst_object_unref (self);
return NULL;
}
return GST_MF_SOURCE_OBJECT (self);
return self;
}