[vlc-devel] [RFC] transform: add motion detection
Pierre Ynard
linkfanel at yahoo.fr
Thu Nov 1 00:37:32 CET 2012
This will allow getting rid of the busy-looping, variable-hacking,
configuration-overriding motion interface. The possible issues are
getting the vout object with filter->p_parent, and not initializing all
the bits of dst? Also it will need a couple tweaks to the motion lib
first to work properly.
diff --git a/modules/video_filter/transform.c b/modules/video_filter/transform.c
index 5c2f1d1..3d374ae 100644
--- a/modules/video_filter/transform.c
+++ b/modules/video_filter/transform.c
@@ -31,10 +31,12 @@
# include "config.h"
#endif
#include <limits.h>
+#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_filter.h>
+#include "../control/motionlib.h"
/*****************************************************************************
* Module descriptor
@@ -46,11 +48,11 @@ static void Close(vlc_object_t *);
#define TYPE_TEXT N_("Transform type")
static const char * const type_list[] = { "90", "180", "270",
- "hflip", "vflip", "transpose", "antitranspose" };
+ "hflip", "vflip", "transpose", "antitranspose", "motion" };
static const char * const type_list_text[] = { N_("Rotate by 90 degrees"),
N_("Rotate by 180 degrees"), N_("Rotate by 270 degrees"),
N_("Flip horizontally"), N_("Flip vertically"),
- N_("Transpose"), N_("Anti-transpose") };
+ N_("Transpose"), N_("Anti-transpose"), N_("Follow motion sensors") };
vlc_module_begin()
set_description(N_("Video transformation filter"))
@@ -236,12 +238,43 @@ struct filter_sys_t {
const vlc_chroma_description_t *chroma;
void (*plane)(plane_t *, const plane_t *);
convert_t convert;
+ motion_sensors_t *motion;
};
+#define LOW_THRESHOLD 800
+#define HIGH_THRESHOLD 1000
+
+/* Check if we need to reset the filter to a new orientation */
+static void check_motion(filter_t *filter)
+{
+ filter_sys_t *sys = filter->p_sys;
+
+ int angle = motion_get_angle(sys->motion);
+
+ if ((sys->convert == NULL
+ && (angle < -HIGH_THRESHOLD || angle > HIGH_THRESHOLD))
+ || (sys->convert == R270 && angle > -LOW_THRESHOLD)
+ || (sys->convert == R90 && angle < LOW_THRESHOLD))
+ {
+ vlc_object_t *p_vout = filter->p_parent;
+ assert(!strcmp(p_vout->psz_object_type, "video output"));
+ var_TriggerCallback(p_vout, "video-filter");
+ }
+}
+
static picture_t *Filter(filter_t *filter, picture_t *src)
{
filter_sys_t *sys = filter->p_sys;
+ if (sys->motion != NULL)
+ {
+ check_motion(filter);
+
+ /* No rotation: the filter is a no-op */
+ if (sys->convert == NULL)
+ return src;
+ }
+
picture_t *dst = filter_NewPicture(filter);
if (!dst) {
picture_Release(src);
@@ -290,6 +323,39 @@ static int Open(vlc_object_t *object)
sys->chroma = chroma;
char *type_name = var_InheritString(filter, CFG_PREFIX"type");
+
+ sys->motion = NULL;
+ if (!strcmp(type_name, "motion"))
+ {
+ free(type_name);
+ sys->motion = motion_create(VLC_OBJECT(filter));
+ if (sys->motion == NULL)
+ goto error;
+
+ int angle = motion_get_angle(sys->motion);
+ if (angle < -HIGH_THRESHOLD)
+ {
+ type_name = "270";
+ msg_Dbg(filter, "Motion detection: rotating by 270 degrees");
+ }
+ else if (angle > HIGH_THRESHOLD)
+ {
+ type_name = "90";
+ msg_Dbg(filter, "Motion detection: rotating by 90 degrees");
+ }
+ else
+ {
+ sys->convert = NULL;
+ sys->plane = NULL;
+ msg_Dbg(filter, "Motion detection: no rotation, keeping "
+ "original orientation");
+
+ filter->p_sys = sys;
+ filter->pf_video_filter = Filter;
+ return VLC_SUCCESS;
+ }
+ }
+
const transform_description_t *dsc = NULL;
for (size_t i = 0; i < n_transforms; i++)
@@ -303,7 +369,8 @@ static int Open(vlc_object_t *object)
dsc->name);
}
- free(type_name);
+ if (sys->motion == NULL)
+ free(type_name);
switch (chroma->pixel_size) {
case 1:
@@ -380,6 +447,8 @@ static int Open(vlc_object_t *object)
filter->pf_video_mouse = Mouse;
return VLC_SUCCESS;
error:
+ if (sys->motion != NULL)
+ motion_destroy(sys->motion);
free(sys);
return VLC_EGENERIC;
}
@@ -389,5 +458,7 @@ static void Close(vlc_object_t *object)
filter_t *filter = (filter_t *)object;
filter_sys_t *sys = filter->p_sys;
+ if (sys->motion != NULL)
+ motion_destroy(sys->motion);
free(sys);
}
Regards,
--
Pierre Ynard
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."
More information about the vlc-devel
mailing list