mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +00:00
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:
parent
f9464ce354
commit
40d0c1aec0
2 changed files with 235 additions and 247 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue