Skip to content

Commit

Permalink
media: vimc: Implement debayer control for mean window size
Browse files Browse the repository at this point in the history
Add mean window size parameter for debayer filter as a control in
vimc-debayer.

vimc-debayer was patched to allow changing mean window parameter
of the filter without needing to reload the driver. The parameter
can now be set using a v4l2-ctl control(mean_window_size).

Co-developed-by: Laís Pessine do Carmo <laispc19@gmail.com>
Signed-off-by: Laís Pessine do Carmo <laispc19@gmail.com>
Signed-off-by: Arthur Moraes do Lago <arthurmoraeslago@gmail.com>
Acked-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
  • Loading branch information
Arthur Moraes do Lago authored and Mauro Carvalho Chehab committed Oct 24, 2019
1 parent b1f8e93 commit 76df2e6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 21 deletions.
10 changes: 1 addition & 9 deletions Documentation/media/v4l-drivers/vimc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ vimc-capture:
Module options
--------------

Vimc has a few module parameters to configure the driver.

param=value
Vimc has a module parameter to configure the driver.

* ``sca_mult=<unsigned int>``

Expand All @@ -91,12 +89,6 @@ Vimc has a few module parameters to configure the driver.
original one. Currently, only supports scaling up (the default value
is 3).

* ``deb_mean_win_size=<unsigned int>``

Window size to calculate the mean. Note: the window size needs to be an
odd number, as the main pixel stays in the center of the window,
otherwise the next odd number is considered (the default value is 3).

Source code documentation
-------------------------

Expand Down
1 change: 1 addition & 0 deletions drivers/media/platform/vimc/vimc-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define VIMC_CID_VIMC_BASE (0x00f00000 | 0xf000)
#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)
#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)
#define VIMC_CID_MEAN_WIN_SIZE (VIMC_CID_VIMC_BASE + 1)

#define VIMC_FRAME_MAX_WIDTH 4096
#define VIMC_FRAME_MAX_HEIGHT 2160
Expand Down
81 changes: 69 additions & 12 deletions drivers/media/platform/vimc/vimc-debayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@
#include <linux/platform_device.h>
#include <linux/vmalloc.h>
#include <linux/v4l2-mediabus.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-subdev.h>

#include "vimc-common.h"

static unsigned int deb_mean_win_size = 3;
module_param(deb_mean_win_size, uint, 0000);
MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
"NOTE: the window size needs to be an odd number, as the main pixel "
"stays in the center of the window, otherwise the next odd number "
"is considered");

enum vimc_deb_rgb_colors {
VIMC_DEB_RED = 0,
VIMC_DEB_GREEN = 1,
Expand All @@ -43,6 +38,8 @@ struct vimc_deb_device {
u8 *src_frame;
const struct vimc_deb_pix_map *sink_pix_map;
unsigned int sink_bpp;
unsigned int mean_win_size;
struct v4l2_ctrl_handler hdl;
struct media_pad pads[2];
};

Expand Down Expand Up @@ -344,11 +341,18 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}

static const struct v4l2_subdev_core_ops vimc_deb_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};

static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
.s_stream = vimc_deb_s_stream,
};

static const struct v4l2_subdev_ops vimc_deb_ops = {
.core = &vimc_deb_core_ops,
.pad = &vimc_deb_pad_ops,
.video = &vimc_deb_video_ops,
};
Expand Down Expand Up @@ -382,7 +386,7 @@ static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
* the top left corner of the mean window (considering the current
* pixel as the center)
*/
seek = deb_mean_win_size / 2;
seek = vdeb->mean_win_size / 2;

/* Sum the values of the colors in the mean window */

Expand Down Expand Up @@ -469,14 +473,33 @@ static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
}

return vdeb->src_frame;
}

static int vimc_deb_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct vimc_deb_device *vdeb =
container_of(ctrl->handler, struct vimc_deb_device, hdl);

switch (ctrl->id) {
case VIMC_CID_MEAN_WIN_SIZE:
vdeb->mean_win_size = ctrl->val;
break;
default:
return -EINVAL;
}
return 0;
}

static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = {
.s_ctrl = vimc_deb_s_ctrl,
};

static void vimc_deb_release(struct v4l2_subdev *sd)
{
struct vimc_deb_device *vdeb =
container_of(sd, struct vimc_deb_device, sd);

v4l2_ctrl_handler_free(&vdeb->hdl);
media_entity_cleanup(vdeb->ved.ent);
kfree(vdeb);
}
Expand All @@ -493,6 +516,24 @@ void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
v4l2_device_unregister_subdev(&vdeb->sd);
}

static const struct v4l2_ctrl_config vimc_deb_ctrl_class = {
.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
.id = VIMC_CID_VIMC_CLASS,
.name = "VIMC Controls",
.type = V4L2_CTRL_TYPE_CTRL_CLASS,
};

static const struct v4l2_ctrl_config vimc_deb_ctrl_mean_win_size = {
.ops = &vimc_deb_ctrl_ops,
.id = VIMC_CID_MEAN_WIN_SIZE,
.name = "Debayer Mean Window Size",
.type = V4L2_CTRL_TYPE_INTEGER,
.min = 1,
.max = 25,
.step = 2,
.def = 3,
};

struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
const char *vcfg_name)
{
Expand All @@ -505,6 +546,16 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
if (!vdeb)
return NULL;

/* Create controls: */
v4l2_ctrl_handler_init(&vdeb->hdl, 2);
v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_class, NULL);
v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_mean_win_size, NULL);
vdeb->sd.ctrl_handler = &vdeb->hdl;
if (vdeb->hdl.error) {
ret = vdeb->hdl.error;
goto err_free_vdeb;
}

/* Initialize ved and sd */
vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
Expand All @@ -514,13 +565,12 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
vdeb->pads,
&vimc_deb_int_ops, &vimc_deb_ops);
if (ret) {
kfree(vdeb);
return NULL;
}
if (ret)
goto err_free_hdl;

vdeb->ved.process_frame = vimc_deb_process_frame;
vdeb->ved.dev = &vimc->pdev.dev;
vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;

/* Initialize the frame format */
vdeb->sink_fmt = sink_fmt_default;
Expand All @@ -534,4 +584,11 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;

return &vdeb->ved;

err_free_hdl:
v4l2_ctrl_handler_free(&vdeb->hdl);
err_free_vdeb:
kfree(vdeb);

return NULL;
}

0 comments on commit 76df2e6

Please sign in to comment.