/* chain function * this function does the actual processing */ static GstFlowReturn gst_edge_detect_chain (GstPad * pad, GstBuffer * buf) { GstEdgeDetect *filter; GstBuffer *outbuf; filter = GST_EDGE_DETECT (GST_OBJECT_PARENT (pad)); filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf); cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); cvSmooth (filter->cvGray, filter->cvEdge, CV_BLUR, 3, 3, 0, 0); cvNot (filter->cvGray, filter->cvEdge); cvCanny (filter->cvGray, filter->cvEdge, filter->threshold1, filter->threshold2, filter->aperture); cvZero (filter->cvCEdge); if (filter->mask) { cvCopy (filter->cvImage, filter->cvCEdge, filter->cvEdge); } else { cvCvtColor (filter->cvEdge, filter->cvCEdge, CV_GRAY2RGB); } outbuf = gst_buffer_new_and_alloc (filter->cvCEdge->imageSize); gst_buffer_copy_metadata (outbuf, buf, GST_BUFFER_COPY_ALL); memcpy (GST_BUFFER_DATA (outbuf), filter->cvCEdge->imageData, GST_BUFFER_SIZE (outbuf)); gst_buffer_unref (buf); return gst_pad_push (filter->srcpad, outbuf); }
/* Clean up */ static void gst_edge_detect_finalize (GObject * obj) { GstEdgeDetect *filter = GST_EDGE_DETECT (obj); if (filter->cvImage != NULL) { cvReleaseImage (&filter->cvImage); cvReleaseImage (&filter->cvCEdge); cvReleaseImage (&filter->cvGray); cvReleaseImage (&filter->cvEdge); } G_OBJECT_CLASS (parent_class)->finalize (obj); }
/* this function handles the link with other elements */ static gboolean gst_edge_detect_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstEdgeDetect *filter; gint width, height; GstStructure *structure; gboolean res = TRUE; filter = GST_EDGE_DETECT (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); if (filter->cvImage != NULL) { cvReleaseImage (&filter->cvImage); cvReleaseImage (&filter->cvCEdge); cvReleaseImage (&filter->cvGray); cvReleaseImage (&filter->cvEdge); } filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvCEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); break; } default: break; } res = gst_pad_event_default (pad, parent, event); return res; }
/* chain function * this function does the actual processing */ static GstFlowReturn gst_edge_detect_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstEdgeDetect *filter; GstBuffer *outbuf; GstMapInfo in_info; GstMapInfo out_info; filter = GST_EDGE_DETECT (parent); buf = gst_buffer_make_writable (buf); gst_buffer_map (buf, &in_info, GST_MAP_WRITE); filter->cvImage->imageData = (char *) in_info.data; cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); cvSmooth (filter->cvGray, filter->cvEdge, CV_BLUR, 3, 3, 0, 0); cvNot (filter->cvGray, filter->cvEdge); cvCanny (filter->cvGray, filter->cvEdge, filter->threshold1, filter->threshold2, filter->aperture); cvZero (filter->cvCEdge); if (filter->mask) { cvCopy (filter->cvImage, filter->cvCEdge, filter->cvEdge); } else { cvCvtColor (filter->cvEdge, filter->cvCEdge, CV_GRAY2RGB); } outbuf = gst_buffer_new_and_alloc (filter->cvCEdge->imageSize); gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1); gst_buffer_map (outbuf, &out_info, GST_MAP_WRITE); memcpy (out_info.data, filter->cvCEdge->imageData, gst_buffer_get_size (outbuf)); gst_buffer_unmap (buf, &in_info); gst_buffer_unmap (outbuf, &out_info); gst_buffer_unref (buf); return gst_pad_push (filter->srcpad, outbuf); }
/* this function handles the link with other elements */ static gboolean gst_edge_detect_set_caps (GstPad * pad, GstCaps * caps) { GstEdgeDetect *filter; GstPad *otherpad; gint width, height; GstStructure *structure; filter = GST_EDGE_DETECT (gst_pad_get_parent (pad)); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvCEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvEdge = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; gst_object_unref (filter); return gst_pad_set_caps (otherpad, caps); }
static void gst_edge_detect_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstEdgeDetect *filter = GST_EDGE_DETECT (object); switch (prop_id) { case PROP_MASK: g_value_set_boolean (value, filter->mask); break; case PROP_THRESHOLD1: g_value_set_int (value, filter->threshold1); break; case PROP_THRESHOLD2: g_value_set_int (value, filter->threshold2); break; case PROP_APERTURE: g_value_set_int (value, filter->aperture); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }