diff --git a/ext/opencv/gsttemplatematch.c b/ext/opencv/gsttemplatematch.c index aea85d660d..7123bdbf27 100644 --- a/ext/opencv/gsttemplatematch.c +++ b/ext/opencv/gsttemplatematch.c @@ -113,7 +113,8 @@ static gboolean gst_template_match_handle_sink_event (GstPad * pad, static GstFlowReturn gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf); -static void gst_template_match_load_template (GstTemplateMatch * filter); +static void gst_template_match_load_template (GstTemplateMatch * filter, + gchar * template); static void gst_template_match_match (IplImage * input, IplImage * template, IplImage * dist_image, double *best_res, CvPoint * best_pos, int method); @@ -190,6 +191,7 @@ gst_template_match_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_METHOD: + GST_OBJECT_LOCK (filter); switch (g_value_get_int (value)) { case 0: filter->method = CV_TM_SQDIFF; @@ -210,13 +212,15 @@ gst_template_match_set_property (GObject * object, guint prop_id, filter->method = CV_TM_CCOEFF_NORMED; break; } + GST_OBJECT_UNLOCK (filter); break; case PROP_TEMPLATE: - filter->template = (char *) g_value_get_string (value); - gst_template_match_load_template (filter); + gst_template_match_load_template (filter, g_value_dup_string (value)); break; case PROP_DISPLAY: + GST_OBJECT_LOCK (filter); filter->display = g_value_get_boolean (value); + GST_OBJECT_UNLOCK (filter); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -290,6 +294,7 @@ gst_template_match_finalize (GObject * object) GstTemplateMatch *filter; filter = GST_TEMPLATE_MATCH (object); + g_free (filter->template); if (filter->cvImage) { cvReleaseImageHeader (&filter->cvImage); } @@ -313,6 +318,7 @@ gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) CvPoint best_pos; double best_res; GstMapInfo info; + GstMessage *m = NULL; filter = GST_TEMPLATE_MATCH (parent); @@ -325,6 +331,7 @@ gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) gst_buffer_map (buf, &info, GST_MAP_READWRITE); filter->cvImage->imageData = (char *) info.data; + GST_OBJECT_LOCK (filter); if (filter->cvTemplateImage && !filter->cvDistImage) { if (filter->cvTemplateImage->width > filter->cvImage->width) { GST_WARNING ("Template Image is wider than input image"); @@ -348,7 +355,6 @@ gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) } if (filter->cvTemplateImage && filter->cvImage && filter->cvDistImage) { GstStructure *s; - GstMessage *m; gst_template_match_match (filter->cvImage, filter->cvTemplateImage, filter->cvDistImage, &best_res, &best_pos, filter->method); @@ -361,7 +367,6 @@ gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) "result", G_TYPE_DOUBLE, best_res, NULL); m = gst_message_new_element (GST_OBJECT (filter), s); - gst_element_post_message (GST_ELEMENT (filter), m); if (filter->display) { CvPoint corner = best_pos; @@ -375,7 +380,11 @@ gst_template_match_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) } } + GST_OBJECT_UNLOCK (filter); + if (m) { + gst_element_post_message (GST_ELEMENT (filter), m); + } return gst_pad_push (filter->srcpad, buf); } @@ -402,22 +411,35 @@ gst_template_match_match (IplImage * input, IplImage * template, } +/* We take ownership of template here */ static void -gst_template_match_load_template (GstTemplateMatch * filter) +gst_template_match_load_template (GstTemplateMatch * filter, gchar * template) { - if (filter->template) { + gchar *oldTemplateFilename = NULL; + IplImage *oldTemplateImage = NULL, *newTemplateImage = NULL, *oldDistImage = + NULL; - if (filter->cvTemplateImage) { - cvReleaseImage (&filter->cvTemplateImage); - } - filter->cvTemplateImage = - cvLoadImage (filter->template, CV_LOAD_IMAGE_COLOR); - - if (!filter->cvTemplateImage) { - GST_WARNING ("Couldn't load template image: %s. error: %s", - filter->template, g_strerror (errno)); + if (template) { + newTemplateImage = cvLoadImage (template, CV_LOAD_IMAGE_COLOR); + if (!newTemplateImage) { + GST_WARNING ("Couldn't load template image: %s. error: %s", + template, g_strerror (errno)); } } + + GST_OBJECT_LOCK (filter); + oldTemplateFilename = filter->template; + filter->template = template; + oldTemplateImage = filter->cvTemplateImage; + filter->cvTemplateImage = newTemplateImage; + oldDistImage = filter->cvDistImage; + /* This will be recreated in the chain function as required: */ + filter->cvDistImage = NULL; + GST_OBJECT_UNLOCK (filter); + + cvReleaseImage (&oldDistImage); + cvReleaseImage (&oldTemplateImage); + g_free (oldTemplateFilename); }