The idea of modet controls through userspace is:
The first of all need select region number (0..3) (it value stores)
And then config thresolds (pixel,motion,trigger) for that region.
Also it`s available setup regions controls (each of 16x16 rects of the frame,
where detection will be approve).
In user space need only add/delete or clear some rect (set 
top,left,width,height)
and system automaticaly set up each 16x16 rects for that.
Clear buttom/menu clears all modet region for detection. (idle work)

Signed-off-by: Volokh Konstantin <volok...@gmail.com>
---
 drivers/staging/media/go7007/go7007-priv.h |    9 ++-
 drivers/staging/media/go7007/go7007-v4l2.c |  120 ++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h 
b/drivers/staging/media/go7007/go7007-priv.h
index fc8aac4..36b271f 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -226,7 +226,14 @@ struct go7007 {
        } modet[4];
        unsigned char modet_map[1624];
        unsigned char active_map[216];
-
+       struct { /* modet type control cluster */
+               struct v4l2_ctrl *modet_clip_left;
+               struct v4l2_ctrl *modet_clip_top;
+               struct v4l2_ctrl *modet_clip_width;
+               struct v4l2_ctrl *modet_clip_height;
+               struct v4l2_ctrl *modet_region_number;
+               //struct v4l2_ctrl *mpeg_video_b_frames;
+       };
        /* Video streaming */
        struct mutex queue_lock;
        struct vb2_queue vidq;
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c 
b/drivers/staging/media/go7007/go7007-v4l2.c
index c4d0ca2..7ea0ea1 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1137,6 +1137,86 @@ static struct video_device go7007_template = {
        .tvnorms        = V4L2_STD_ALL,
 };
 
+static void ClearModetMap(struct go7007 *go, char Region)
+{
+       /* Clear old region macroblocks */
+       int mbnum;
+
+       for (mbnum = 0; mbnum < sizeof(go->modet_map); ++mbnum)
+               if (go->modet_map[mbnum] == Region)
+                       go->modet_map[mbnum] = 0;
+}
+
+static int RectToModetMap(struct go7007 *go,unsigned char Region,int Delete)
+{
+       register int x, y, mbnum;
+       struct v4l2_rect Rect;
+
+       Rect.left=v4l2_ctrl_g_ctrl(go->modet_clip_left);
+       Rect.top=v4l2_ctrl_g_ctrl(go->modet_clip_top);
+       Rect.width=v4l2_ctrl_g_ctrl(go->modet_clip_width);
+       Rect.height=v4l2_ctrl_g_ctrl(go->modet_clip_height);
+       /*!
+        * Check if coordinates are OK and if any macroblocks are already
+        * used by other regions (besides 0)
+        */
+
+       if (Rect.left < 0 || (Rect.left & 0xF) || Rect.width <= 0 || 
(Rect.width & 0xF))
+               return -EINVAL;
+
+       if (Rect.left+Rect.width > go->width)
+               return -EINVAL;
+
+       if (Rect.top < 0 || (Rect.top & 0xF) || Rect.height <= 0 || 
(Rect.height & 0xF))
+               return -EINVAL;
+
+       if (Rect.top+Rect.height > go->height)
+               return -EINVAL;
+
+       for (y = 0; y < Rect.height; y += 16)
+               for (x = 0; x < Rect.width; x += 16) {
+                       mbnum = 
(go->width>>4)*((Rect.top+y)>>4)+((Rect.left+x)>>4);
+               if (go->modet_map[mbnum] != 0 && go->modet_map[mbnum] != Region)
+                       return -EBUSY;
+               else
+               go->modet_map[mbnum] = Delete ? 0 : Region;
+       }
+       return 0;
+}
+
+void go7007_md_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) {
+       struct go7007 *go=priv;
+       int reg_num=v4l2_ctrl_g_ctrl(go->modet_region_number);
+
+       switch(ctrl->id) {
+       case V4L2_CID_USER_MODET_PIXEL_THRESOLD:
+               go->modet[reg_num].pixel_threshold = v4l2_ctrl_g_ctrl(ctrl) >> 
1;
+               break;
+       case V4L2_CID_USER_MODET_MOTION_THRESOLD:
+               go->modet[reg_num].motion_threshold = v4l2_ctrl_g_ctrl(ctrl) >> 
1;
+               break;
+       case V4L2_CID_USER_MODET_TRIGGER:
+               go->modet[reg_num].mb_threshold = v4l2_ctrl_g_ctrl(ctrl) >> 1;
+               go->modet[reg_num].enable = v4l2_ctrl_g_ctrl(ctrl) > 0;
+               break;
+       case V4L2_CID_USER_MODET_REGION_CONTROL:
+               switch (v4l2_ctrl_g_ctrl(ctrl)) {
+               case rcAdd:
+                       RectToModetMap(go, reg_num, 0);
+                       break;
+               case rcDelete:
+                       RectToModetMap(go, reg_num, 1);
+                       break;
+               case rcClear:
+                       ClearModetMap(go, reg_num);
+                       break;
+               default:
+                       break;
+               }
+               break;
+       }
+}
+
 static struct v4l2_ctrl_config md_configs[] = {
        {
                .ops = &go7007_ctrl_ops
@@ -1232,6 +1312,44 @@ static struct v4l2_ctrl_config md_configs[] = {
        }
 };
 
+static int go7007_md_ctrl_init(struct go7007 *go)
+{
+       struct v4l2_ctrl_handler *hdl = &go->hdl;
+       struct v4l2_ctrl *ctrl;
+
+       go->modet_region_number = v4l2_ctrl_new_custom(hdl, &md_configs[0], go);
+
+       ctrl = v4l2_ctrl_new_custom(hdl, &md_configs[1], go);
+       if(ctrl)
+               v4l2_ctrl_notify(ctrl,go7007_md_ctrl_notify,go);
+
+       ctrl = v4l2_ctrl_new_custom(hdl, &md_configs[2], go);
+       if(ctrl)
+               v4l2_ctrl_notify(ctrl,go7007_md_ctrl_notify,go);
+
+       ctrl = v4l2_ctrl_new_custom(hdl, &md_configs[3], go);
+       if(ctrl)
+               v4l2_ctrl_notify(ctrl,go7007_md_ctrl_notify,go);
+
+       md_configs[4].max = go->width-1;
+       go->modet_clip_left = v4l2_ctrl_new_custom(hdl, &md_configs[4], go);
+
+       md_configs[5].max = go->height-1;
+       go->modet_clip_top = v4l2_ctrl_new_custom(hdl, &md_configs[5], go);
+
+       md_configs[6].max = go->width;
+       go->modet_clip_width = v4l2_ctrl_new_custom(hdl, &md_configs[6], go);
+
+       md_configs[7].max = go->height;
+       go->modet_clip_height = v4l2_ctrl_new_custom(hdl, &md_configs[7], go);
+
+       ctrl = v4l2_ctrl_new_custom(hdl, &md_configs[8], go);
+       if(ctrl)
+               v4l2_ctrl_notify(ctrl,go7007_md_ctrl_notify,go);
+
+       return 0;
+}
+
 int go7007_v4l2_ctrl_init(struct go7007 *go)
 {
        struct v4l2_ctrl_handler *hdl = &go->hdl;
@@ -1268,6 +1386,8 @@ int go7007_v4l2_ctrl_init(struct go7007 *go)
                        V4L2_JPEG_ACTIVE_MARKER_DQT | 
V4L2_JPEG_ACTIVE_MARKER_DHT);
        if (ctrl)
                ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+       go7007_md_ctrl_init(go);
        if (hdl->error) {
                rv = hdl->error;
                v4l2_err(&go->v4l2_dev, "Could not register controls\n");
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to