opencv: update motioncells to GstOpencvVideoFilter

Update motioncells to inherit from GstOpencvVideoFilter instead of from
GstElement. This means less code and more uniformity with other OpenCV
elements.
This commit is contained in:
Luis de Bethencourt 2015-12-18 12:28:23 +00:00
parent f9464ce354
commit 40d0c1aec0
2 changed files with 235 additions and 247 deletions

View file

@ -141,7 +141,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB"))); GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")));
G_DEFINE_TYPE (GstMotioncells, gst_motion_cells, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstMotioncells, gst_motion_cells, GST_TYPE_OPENCV_VIDEO_FILTER);
static void gst_motion_cells_set_property (GObject * object, guint prop_id, static void gst_motion_cells_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -150,8 +150,8 @@ static void gst_motion_cells_get_property (GObject * object, guint prop_id,
static gboolean gst_motion_cells_handle_sink_event (GstPad * pad, static gboolean gst_motion_cells_handle_sink_event (GstPad * pad,
GstObject * parent, GstEvent * event); GstObject * parent, GstEvent * event);
static GstFlowReturn gst_motion_cells_chain (GstPad * pad, GstObject * parent, static GstFlowReturn gst_motion_cells_transform_ip (GstOpencvVideoFilter *
GstBuffer * buf); filter, GstBuffer * buf, IplImage * img);
static void gst_motioncells_update_motion_cells (GstMotioncells * filter); static void gst_motioncells_update_motion_cells (GstMotioncells * filter);
static void gst_motioncells_update_motion_masks (GstMotioncells * filter); static void gst_motioncells_update_motion_masks (GstMotioncells * filter);
@ -176,10 +176,6 @@ gst_motion_cells_finalize (GObject * obj)
GFREE (filter->motioncellsidx); GFREE (filter->motioncellsidx);
} }
if (filter->cvImage) {
cvReleaseImage (&filter->cvImage);
}
GFREE (filter->motioncellscolor); GFREE (filter->motioncellscolor);
GFREE (filter->prev_datafile); GFREE (filter->prev_datafile);
GFREE (filter->cur_datafile); GFREE (filter->cur_datafile);
@ -194,22 +190,28 @@ static void
gst_motion_cells_class_init (GstMotioncellsClass * klass) gst_motion_cells_class_init (GstMotioncellsClass * klass)
{ {
GObjectClass *gobject_class; GObjectClass *gobject_class;
GstOpencvVideoFilterClass *gstopencvbasefilter_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass;
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_motion_cells_finalize); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_motion_cells_finalize);
gobject_class->set_property = gst_motion_cells_set_property; gobject_class->set_property = gst_motion_cells_set_property;
gobject_class->get_property = gst_motion_cells_get_property; gobject_class->get_property = gst_motion_cells_get_property;
gstopencvbasefilter_class->cv_trans_ip_func = gst_motion_cells_transform_ip;
g_object_class_install_property (gobject_class, PROP_GRID_X, g_object_class_install_property (gobject_class, PROP_GRID_X,
g_param_spec_int ("gridx", "Number of Horizontal Grids", g_param_spec_int ("gridx", "Number of Horizontal Grids",
"You can give number of horizontal grid cells.", GRID_MIN, GRID_MAX, "You can give number of horizontal grid cells.", GRID_MIN, GRID_MAX,
GRID_DEF, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); GRID_DEF,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_GRID_Y, g_object_class_install_property (gobject_class, PROP_GRID_Y,
g_param_spec_int ("gridy", "Number of Vertical Grids", g_param_spec_int ("gridy", "Number of Vertical Grids",
"You can give number of vertical grid cells.", GRID_MIN, GRID_MAX, "You can give number of vertical grid cells.", GRID_MIN, GRID_MAX,
GRID_DEF, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); GRID_DEF,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_SENSITIVITY, g_object_class_install_property (gobject_class, PROP_SENSITIVITY,
g_param_spec_double ("sensitivity", "Motion Sensitivity", g_param_spec_double ("sensitivity", "Motion Sensitivity",
"You can tunning the element motion sensitivity.", SENSITIVITY_MIN, "You can tunning the element motion sensitivity.", SENSITIVITY_MIN,
@ -315,19 +317,8 @@ gst_motion_cells_class_init (GstMotioncellsClass * klass)
static void static void
gst_motion_cells_init (GstMotioncells * filter) gst_motion_cells_init (GstMotioncells * filter)
{ {
filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); gst_pad_set_event_function (GST_BASE_TRANSFORM_SINK_PAD (filter),
GST_PAD_SET_PROXY_CAPS (filter->sinkpad);
gst_pad_set_event_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_motion_cells_handle_sink_event)); GST_DEBUG_FUNCPTR (gst_motion_cells_handle_sink_event));
gst_pad_set_chain_function (filter->sinkpad,
GST_DEBUG_FUNCPTR (gst_motion_cells_chain));
filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
GST_PAD_SET_PROXY_CAPS (filter->srcpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
filter->display = TRUE; filter->display = TRUE;
filter->calculate_motion = TRUE; filter->calculate_motion = TRUE;
@ -385,6 +376,8 @@ gst_motion_cells_init (GstMotioncells * filter)
filter->datafileidx = 0; filter->datafileidx = 0;
filter->id = motion_cells_init (); filter->id = motion_cells_init ();
gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER_CAST (filter),
TRUE);
} }
static void static void
@ -821,11 +814,6 @@ gst_motion_cells_handle_sink_event (GstPad * pad, GstObject * parent,
filter->height = info.height; filter->height = info.height;
filter->framerate = (double) info.fps_n / (double) info.fps_d; filter->framerate = (double) info.fps_n / (double) info.fps_d;
if (filter->cvImage)
cvReleaseImage (&filter->cvImage);
filter->cvImage =
cvCreateImage (cvSize (filter->width, filter->height), IPL_DEPTH_8U,
3);
break; break;
} }
default: default:
@ -835,19 +823,17 @@ gst_motion_cells_handle_sink_event (GstPad * pad, GstObject * parent,
res = gst_pad_event_default (pad, parent, event); res = gst_pad_event_default (pad, parent, event);
return res; return res;
} }
/* chain function /* chain function
* this function does the actual processing * this function does the actual processing
*/ */
static GstFlowReturn static GstFlowReturn
gst_motion_cells_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) gst_motion_cells_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
IplImage * img)
{ {
GstMotioncells *filter; GstMotioncells *filter = gst_motion_cells (base);
GstMapInfo info;
filter = gst_motion_cells (parent);
GST_OBJECT_LOCK (filter); GST_OBJECT_LOCK (filter);
if (filter->calculate_motion) { if (filter->calculate_motion) {
double sensitivity; double sensitivity;
@ -866,230 +852,235 @@ gst_motion_cells_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
motioncellidx *motioncellsidx; motioncellidx *motioncellsidx;
buf = gst_buffer_make_writable (buf); buf = gst_buffer_make_writable (buf);
if (gst_buffer_map (buf, &info, GST_MAP_WRITE)) { if (filter->firstframe) {
filter->cvImage->imageData = (char *) info.data; setPrevFrame (img, filter->id);
if (filter->firstframe) { filter->firstframe = FALSE;
setPrevFrame (filter->cvImage, filter->id); }
filter->firstframe = FALSE;
}
minimum_motion_frames = filter->minimum_motion_frames;
postnomotion = filter->postnomotion;
sensitivity = filter->sensitivity;
framerate = filter->framerate;
gridx = filter->gridx;
gridy = filter->gridy;
display = filter->display;
motionmaskcoord_count = filter->motionmaskcoord_count;
motionmaskcoords =
g_new0 (motionmaskcoordrect, filter->motionmaskcoord_count);
for (i = 0; i < filter->motionmaskcoord_count; i++) { //we need divide 2 because we use gauss pyramid in C++ side
motionmaskcoords[i].upper_left_x =
filter->motionmaskcoords[i].upper_left_x / 2;
motionmaskcoords[i].upper_left_y =
filter->motionmaskcoords[i].upper_left_y / 2;
motionmaskcoords[i].lower_right_x =
filter->motionmaskcoords[i].lower_right_x / 2;
motionmaskcoords[i].lower_right_y =
filter->motionmaskcoords[i].lower_right_y / 2;
}
motioncellscolor.R_channel_value = minimum_motion_frames = filter->minimum_motion_frames;
filter->motioncellscolor->R_channel_value; postnomotion = filter->postnomotion;
motioncellscolor.G_channel_value = sensitivity = filter->sensitivity;
filter->motioncellscolor->G_channel_value; framerate = filter->framerate;
motioncellscolor.B_channel_value = gridx = filter->gridx;
filter->motioncellscolor->B_channel_value; gridy = filter->gridy;
display = filter->display;
motionmaskcoord_count = filter->motionmaskcoord_count;
motionmaskcoords =
g_new0 (motionmaskcoordrect, filter->motionmaskcoord_count);
for (i = 0; i < filter->motionmaskcoord_count; i++) { //we need divide 2 because we use gauss pyramid in C++ side
motionmaskcoords[i].upper_left_x =
filter->motionmaskcoords[i].upper_left_x / 2;
motionmaskcoords[i].upper_left_y =
filter->motionmaskcoords[i].upper_left_y / 2;
motionmaskcoords[i].lower_right_x =
filter->motionmaskcoords[i].lower_right_x / 2;
motionmaskcoords[i].lower_right_y =
filter->motionmaskcoords[i].lower_right_y / 2;
}
if ((filter->changed_gridx || filter->changed_gridy motioncellscolor.R_channel_value =
|| filter->changed_startime)) { filter->motioncellscolor->R_channel_value;
if ((g_strcmp0 (filter->cur_datafile, NULL) != 0)) { motioncellscolor.G_channel_value =
GFREE (filter->cur_datafile); filter->motioncellscolor->G_channel_value;
filter->datafileidx++; motioncellscolor.B_channel_value =
filter->cur_datafile = filter->motioncellscolor->B_channel_value;
g_strdup_printf ("%s-%d.%s", filter->basename_datafile,
filter->datafileidx, filter->datafile_extension);
filter->changed_datafile = TRUE;
motion_cells_free_resources (filter->id);
}
if (filter->motioncells_count > 0)
gst_motioncells_update_motion_cells (filter);
if (filter->motionmaskcells_count > 0)
gst_motioncells_update_motion_masks (filter);
filter->changed_gridx = FALSE;
filter->changed_gridy = FALSE;
filter->changed_startime = FALSE;
}
datafile = g_strdup (filter->cur_datafile);
filter->cur_buff_timestamp = (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND);
filter->starttime +=
(filter->cur_buff_timestamp - filter->prev_buff_timestamp);
starttime = filter->starttime;
if (filter->changed_datafile || filter->diff_timestamp < 0)
filter->diff_timestamp =
(gint64) (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND);
changed_datafile = filter->changed_datafile;
motionmaskcells_count = filter->motionmaskcells_count;
motionmaskcellsidx =
g_new0 (motioncellidx, filter->motionmaskcells_count);
for (i = 0; i < filter->motionmaskcells_count; i++) {
motionmaskcellsidx[i].lineidx = filter->motionmaskcellsidx[i].lineidx;
motionmaskcellsidx[i].columnidx =
filter->motionmaskcellsidx[i].columnidx;
}
motioncells_count = filter->motioncells_count;
motioncellsidx = g_new0 (motioncellidx, filter->motioncells_count);
for (i = 0; i < filter->motioncells_count; i++) {
motioncellsidx[i].lineidx = filter->motioncellsidx[i].lineidx;
motioncellsidx[i].columnidx = filter->motioncellsidx[i].columnidx;
}
useAlpha = filter->usealpha;
thickness = filter->thickness;
success =
perform_detection_motion_cells (filter->cvImage, sensitivity,
framerate, gridx, gridy,
(gint64) (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND) -
filter->diff_timestamp, display, useAlpha, motionmaskcoord_count,
motionmaskcoords, motionmaskcells_count, motionmaskcellsidx,
motioncellscolor, motioncells_count, motioncellsidx, starttime,
datafile, changed_datafile, thickness, filter->id);
if ((success == 1) && (filter->sent_init_error_msg == FALSE)) { if ((filter->changed_gridx || filter->changed_gridy
char *initfailedreason; || filter->changed_startime)) {
int initerrorcode; if ((g_strcmp0 (filter->cur_datafile, NULL) != 0)) {
GstStructure *s; GFREE (filter->cur_datafile);
GstMessage *m; filter->datafileidx++;
initfailedreason = getInitDataFileFailed (filter->id); filter->cur_datafile =
initerrorcode = getInitErrorCode (filter->id); g_strdup_printf ("%s-%d.%s", filter->basename_datafile,
s = gst_structure_new ("motion", "init_error_code", G_TYPE_INT, filter->datafileidx, filter->datafile_extension);
initerrorcode, "details", G_TYPE_STRING, initfailedreason, NULL); filter->changed_datafile = TRUE;
m = gst_message_new_element (GST_OBJECT (filter), s); motion_cells_free_resources (filter->id);
gst_element_post_message (GST_ELEMENT (filter), m);
filter->sent_init_error_msg = TRUE;
} }
if ((success == -1) && (filter->sent_save_error_msg == FALSE)) { if (filter->motioncells_count > 0)
char *savefailedreason; gst_motioncells_update_motion_cells (filter);
int saveerrorcode; if (filter->motionmaskcells_count > 0)
GstStructure *s; gst_motioncells_update_motion_masks (filter);
GstMessage *m; filter->changed_gridx = FALSE;
savefailedreason = getSaveDataFileFailed (filter->id); filter->changed_gridy = FALSE;
saveerrorcode = getSaveErrorCode (filter->id); filter->changed_startime = FALSE;
s = gst_structure_new ("motion", "save_error_code", G_TYPE_INT, }
saveerrorcode, "details", G_TYPE_STRING, savefailedreason, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s); datafile = g_strdup (filter->cur_datafile);
gst_element_post_message (GST_ELEMENT (filter), m); filter->cur_buff_timestamp = (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND);
filter->sent_save_error_msg = TRUE; filter->starttime +=
} (filter->cur_buff_timestamp - filter->prev_buff_timestamp);
if (success == -2) { starttime = filter->starttime;
GST_LOG_OBJECT (filter, "frame dropped"); if (filter->changed_datafile || filter->diff_timestamp < 0)
gst_buffer_unmap (buf, &info); filter->diff_timestamp =
filter->prev_buff_timestamp = filter->cur_buff_timestamp; (gint64) (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND);
//free changed_datafile = filter->changed_datafile;
GFREE (datafile);
GFREE (motionmaskcoords); motionmaskcells_count = filter->motionmaskcells_count;
GFREE (motionmaskcellsidx); motionmaskcellsidx = g_new0 (motioncellidx, filter->motionmaskcells_count);
GFREE (motioncellsidx); for (i = 0; i < filter->motionmaskcells_count; i++) {
GST_OBJECT_UNLOCK (filter); motionmaskcellsidx[i].lineidx = filter->motionmaskcellsidx[i].lineidx;
return gst_pad_push (filter->srcpad, buf); motionmaskcellsidx[i].columnidx = filter->motionmaskcellsidx[i].columnidx;
} }
filter->changed_datafile = getChangedDataFile (filter->id); motioncells_count = filter->motioncells_count;
motioncellsidxcnt = getMotionCellsIdxCnt (filter->id); motioncellsidx = g_new0 (motioncellidx, filter->motioncells_count);
numberOfCells = filter->gridx * filter->gridy; for (i = 0; i < filter->motioncells_count; i++) {
motioncellsnumber = motioncellsidxcnt / MSGLEN; motioncellsidx[i].lineidx = filter->motioncellsidx[i].lineidx;
cellsOfInterestNumber = (filter->motioncells_count > 0) ? //how many cells interest for us motioncellsidx[i].columnidx = filter->motioncellsidx[i].columnidx;
(filter->motioncells_count) : (numberOfCells); }
mincellsOfInterestNumber =
floor ((double) cellsOfInterestNumber * filter->threshold); useAlpha = filter->usealpha;
GST_OBJECT_UNLOCK (filter); thickness = filter->thickness;
motiondetect = (motioncellsnumber >= mincellsOfInterestNumber) ? 1 : 0; success =
if ((motioncellsidxcnt > 0) && (motiondetect == 1)) { perform_detection_motion_cells (img, sensitivity,
char *detectedmotioncells; framerate, gridx, gridy,
filter->last_motion_timestamp = GST_BUFFER_TIMESTAMP (buf); (gint64) (GST_BUFFER_TIMESTAMP (buf) / GST_MSECOND) -
detectedmotioncells = getMotionCellsIdx (filter->id); filter->diff_timestamp, display, useAlpha, motionmaskcoord_count,
if (detectedmotioncells) { motionmaskcoords, motionmaskcells_count, motionmaskcellsidx,
filter->consecutive_motion++; motioncellscolor, motioncells_count, motioncellsidx, starttime,
if ((filter->previous_motion == FALSE) datafile, changed_datafile, thickness, filter->id);
&& (filter->consecutive_motion >= minimum_motion_frames)) {
GstStructure *s; if ((success == 1) && (filter->sent_init_error_msg == FALSE)) {
GstMessage *m; char *initfailedreason;
GST_DEBUG_OBJECT (filter, "motion started, post msg on the bus"); int initerrorcode;
filter->previous_motion = TRUE; GstStructure *s;
filter->motion_begin_timestamp = GST_BUFFER_TIMESTAMP (buf); GstMessage *m;
s = gst_structure_new ("motion", "motion_cells_indices",
G_TYPE_STRING, detectedmotioncells, "motion_begin", initfailedreason = getInitDataFileFailed (filter->id);
G_TYPE_UINT64, filter->motion_begin_timestamp, NULL); initerrorcode = getInitErrorCode (filter->id);
m = gst_message_new_element (GST_OBJECT (filter), s); s = gst_structure_new ("motion", "init_error_code", G_TYPE_INT,
gst_element_post_message (GST_ELEMENT (filter), m); initerrorcode, "details", G_TYPE_STRING, initfailedreason, NULL);
} else if (filter->postallmotion) { m = gst_message_new_element (GST_OBJECT (filter), s);
GstStructure *s; gst_element_post_message (GST_ELEMENT (filter), m);
GstMessage *m; filter->sent_init_error_msg = TRUE;
GST_DEBUG_OBJECT (filter, "motion, post msg on the bus"); }
filter->motion_timestamp = GST_BUFFER_TIMESTAMP (buf); if ((success == -1) && (filter->sent_save_error_msg == FALSE)) {
s = gst_structure_new ("motion", "motion_cells_indices", char *savefailedreason;
G_TYPE_STRING, detectedmotioncells, "motion", G_TYPE_UINT64, int saveerrorcode;
filter->motion_timestamp, NULL); GstStructure *s;
m = gst_message_new_element (GST_OBJECT (filter), s); GstMessage *m;
gst_element_post_message (GST_ELEMENT (filter), m);
} savefailedreason = getSaveDataFileFailed (filter->id);
} else { saveerrorcode = getSaveErrorCode (filter->id);
GstStructure *s; s = gst_structure_new ("motion", "save_error_code", G_TYPE_INT,
GstMessage *m; saveerrorcode, "details", G_TYPE_STRING, savefailedreason, NULL);
s = gst_structure_new ("motion", "motion_cells_indices", m = gst_message_new_element (GST_OBJECT (filter), s);
G_TYPE_STRING, "error", NULL); gst_element_post_message (GST_ELEMENT (filter), m);
m = gst_message_new_element (GST_OBJECT (filter), s); filter->sent_save_error_msg = TRUE;
gst_element_post_message (GST_ELEMENT (filter), m); }
} if (success == -2) {
} else { GST_LOG_OBJECT (filter, "frame dropped");
filter->consecutive_motion = 0;
if ((((GST_BUFFER_TIMESTAMP (buf) -
filter->last_motion_timestamp) / 1000000000l) >=
filter->gap)
&& (filter->last_motion_timestamp > 0)) {
if (filter->previous_motion) {
GstStructure *s;
GstMessage *m;
GST_DEBUG_OBJECT (filter, "motion finished, post msg on the bus");
filter->previous_motion = FALSE;
s = gst_structure_new ("motion", "motion_finished", G_TYPE_UINT64,
filter->last_motion_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
}
}
if (postnomotion > 0) {
guint64 last_buf_timestamp = GST_BUFFER_TIMESTAMP (buf) / 1000000000l;
if ((last_buf_timestamp -
(filter->last_motion_timestamp / 1000000000l)) >=
filter->postnomotion) {
GST_DEBUG_OBJECT (filter, "post no motion msg on the bus");
if ((last_buf_timestamp -
(filter->last_nomotion_notified / 1000000000l)) >=
filter->postnomotion) {
GstStructure *s;
GstMessage *m;
filter->last_nomotion_notified = GST_BUFFER_TIMESTAMP (buf);
s = gst_structure_new ("motion", "no_motion", G_TYPE_UINT64,
filter->last_motion_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
}
}
gst_buffer_unmap (buf, &info);
filter->prev_buff_timestamp = filter->cur_buff_timestamp; filter->prev_buff_timestamp = filter->cur_buff_timestamp;
//free //free
GFREE (datafile); GFREE (datafile);
GFREE (motionmaskcoords); GFREE (motionmaskcoords);
GFREE (motionmaskcellsidx); GFREE (motionmaskcellsidx);
GFREE (motioncellsidx); GFREE (motioncellsidx);
} else {
GST_WARNING_OBJECT (filter, "error mapping input buffer");
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
return GST_FLOW_OK;
} }
filter->changed_datafile = getChangedDataFile (filter->id);
motioncellsidxcnt = getMotionCellsIdxCnt (filter->id);
numberOfCells = filter->gridx * filter->gridy;
motioncellsnumber = motioncellsidxcnt / MSGLEN;
cellsOfInterestNumber = (filter->motioncells_count > 0) ? //how many cells interest for us
(filter->motioncells_count) : (numberOfCells);
mincellsOfInterestNumber =
floor ((double) cellsOfInterestNumber * filter->threshold);
GST_OBJECT_UNLOCK (filter);
motiondetect = (motioncellsnumber >= mincellsOfInterestNumber) ? 1 : 0;
if ((motioncellsidxcnt > 0) && (motiondetect == 1)) {
char *detectedmotioncells;
filter->last_motion_timestamp = GST_BUFFER_TIMESTAMP (buf);
detectedmotioncells = getMotionCellsIdx (filter->id);
if (detectedmotioncells) {
filter->consecutive_motion++;
if ((filter->previous_motion == FALSE)
&& (filter->consecutive_motion >= minimum_motion_frames)) {
GstStructure *s;
GstMessage *m;
GST_DEBUG_OBJECT (filter, "motion started, post msg on the bus");
filter->previous_motion = TRUE;
filter->motion_begin_timestamp = GST_BUFFER_TIMESTAMP (buf);
s = gst_structure_new ("motion", "motion_cells_indices",
G_TYPE_STRING, detectedmotioncells, "motion_begin",
G_TYPE_UINT64, filter->motion_begin_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
} else if (filter->postallmotion) {
GstStructure *s;
GstMessage *m;
GST_DEBUG_OBJECT (filter, "motion, post msg on the bus");
filter->motion_timestamp = GST_BUFFER_TIMESTAMP (buf);
s = gst_structure_new ("motion", "motion_cells_indices",
G_TYPE_STRING, detectedmotioncells, "motion", G_TYPE_UINT64,
filter->motion_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
} else {
GstStructure *s;
GstMessage *m;
s = gst_structure_new ("motion", "motion_cells_indices",
G_TYPE_STRING, "error", NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
} else {
filter->consecutive_motion = 0;
if ((((GST_BUFFER_TIMESTAMP (buf) -
filter->last_motion_timestamp) / 1000000000l) >=
filter->gap)
&& (filter->last_motion_timestamp > 0)) {
if (filter->previous_motion) {
GstStructure *s;
GstMessage *m;
GST_DEBUG_OBJECT (filter, "motion finished, post msg on the bus");
filter->previous_motion = FALSE;
s = gst_structure_new ("motion", "motion_finished", G_TYPE_UINT64,
filter->last_motion_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
}
}
if (postnomotion > 0) {
guint64 last_buf_timestamp = GST_BUFFER_TIMESTAMP (buf) / 1000000000l;
if ((last_buf_timestamp -
(filter->last_motion_timestamp / 1000000000l)) >=
filter->postnomotion) {
GST_DEBUG_OBJECT (filter, "post no motion msg on the bus");
if ((last_buf_timestamp -
(filter->last_nomotion_notified / 1000000000l)) >=
filter->postnomotion) {
GstStructure *s;
GstMessage *m;
filter->last_nomotion_notified = GST_BUFFER_TIMESTAMP (buf);
s = gst_structure_new ("motion", "no_motion", G_TYPE_UINT64,
filter->last_motion_timestamp, NULL);
m = gst_message_new_element (GST_OBJECT (filter), s);
gst_element_post_message (GST_ELEMENT (filter), m);
}
}
}
filter->prev_buff_timestamp = filter->cur_buff_timestamp;
//free
GFREE (datafile);
GFREE (motionmaskcoords);
GFREE (motionmaskcellsidx);
GFREE (motioncellsidx);
} else { } else {
GST_WARNING_OBJECT (filter, "error mapping input buffer");
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
} }
return gst_pad_push (filter->srcpad, buf); return GST_FLOW_OK;
} }
/* entry point to initialize the plug-in /* entry point to initialize the plug-in

View file

@ -45,8 +45,7 @@
#ifndef __GST_MOTIONCELLS_H__ #ifndef __GST_MOTIONCELLS_H__
#define __GST_MOTIONCELLS_H__ #define __GST_MOTIONCELLS_H__
#include <gst/gst.h> #include <gstopencvvideofilter.h>
#include <gst/video/video.h>
#include <opencv2/core/core_c.h> #include <opencv2/core/core_c.h>
#include "motioncells_wrapper.h" #include "motioncells_wrapper.h"
@ -67,8 +66,7 @@ typedef struct _GstMotioncellsClass GstMotioncellsClass;
struct _GstMotioncells struct _GstMotioncells
{ {
GstElement element; GstOpencvVideoFilter element;
GstPad *sinkpad, *srcpad;
GstState state; GstState state;
gboolean display, calculate_motion, firstgridx, firstgridy, changed_gridx, gboolean display, calculate_motion, firstgridx, firstgridy, changed_gridx,
changed_gridy, changed_startime; changed_gridy, changed_startime;
@ -78,7 +76,6 @@ struct _GstMotioncells
gchar *prev_datafile, *cur_datafile, *basename_datafile, *datafile_extension; gchar *prev_datafile, *cur_datafile, *basename_datafile, *datafile_extension;
gint prevgridx, gridx, prevgridy, gridy, id; gint prevgridx, gridx, prevgridy, gridy, id;
gdouble sensitivity, threshold; gdouble sensitivity, threshold;
IplImage *cvImage;
motionmaskcoordrect *motionmaskcoords; motionmaskcoordrect *motionmaskcoords;
cellscolor *motioncellscolor; cellscolor *motioncellscolor;
motioncellidx *motioncellsidx, *motionmaskcellsidx; motioncellidx *motioncellsidx, *motionmaskcellsidx;
@ -97,7 +94,7 @@ struct _GstMotioncells
struct _GstMotioncellsClass struct _GstMotioncellsClass
{ {
GstElementClass parent_class; GstOpencvVideoFilterClass parent_class;
}; };
GType gst_motion_cells_get_type (void); GType gst_motion_cells_get_type (void);