From 0b6a248f0ab3251a82ceb0e9189b37ea0678b7bc Mon Sep 17 00:00:00 2001 From: Marko Ollonen Date: Thu, 15 Nov 2012 08:54:56 +0200 Subject: [PATCH] white balance control added. Change-Id: I91907cf31b673d5798cf756df87ac0bf358b246d --- gst-libs/atomisphal/gstv4l2mfldadvci.c | 24 +++- gst-libs/atomisphal/gstv4l2mfldadvci.h | 5 + gst-libs/atomisphal/mfld_cam.c | 3 + gst-libs/gst/camera/gstmfldcameracolorbalance.c | 13 +++ gst-libs/gst/camera/gstmfldcameracolorbalance.h | 43 +++++++ gst/mfldv4l2cam/v4l2camsrc_calls.c | 143 ++++++++++++++++-------- packaging/mfldv4l2camsrc.changes | 3 + packaging/mfldv4l2camsrc.spec | 2 +- 8 files changed, 187 insertions(+), 49 deletions(-) diff --git a/gst-libs/atomisphal/gstv4l2mfldadvci.c b/gst-libs/atomisphal/gstv4l2mfldadvci.c index da7937b..10f0693 100644 --- a/gst-libs/atomisphal/gstv4l2mfldadvci.c +++ b/gst-libs/atomisphal/gstv4l2mfldadvci.c @@ -423,16 +423,16 @@ static void lib_3a_AeAfAwb_process( struct timeval *frame_timestamp) { int status; - cam_lib_3a_dbg("%s:%d\n", __func__, __LINE__); + //cam_lib_3a_dbg("%s:%d\n", __func__, __LINE__); status = ci_adv_process_frame(TRUE,frame_timestamp); } static void lib_3a_get_statistics( ) { - cam_lib_3a_dbg("%s:%d\n", __func__, __LINE__); + // cam_lib_3a_dbg("%s:%d\n", __func__, __LINE__); ci_adv_3a_stat cur_stat; ci_adv_get_3a_stat (&cur_stat); - cam_lib_3a_dbg("%8.3f, %8.3f, %8.3f, %8.3f, %8d, %8.3f, %8.3f, %8.3f\n", + /* cam_lib_3a_dbg("%8.3f, %8.3f, %8.3f, %8.3f, %8d, %8.3f, %8.3f, %8.3f\n", cur_stat.bv, cur_stat.tv, cur_stat.sv, @@ -441,12 +441,28 @@ lib_3a_get_statistics( ) cur_stat.wb_gain_r, cur_stat.wb_gain_g, cur_stat.wb_gain_b); +*/ } static void lib_3a_awb_apply_results( ) { } +static void +lib_3a_AwbSetImageEffect(ia_3a_image_effect effect) +{ + cam_lib_3a_dbg("%s:%d effect %d\n", __func__, __LINE__, effect); + + ci_adv_isp_set_image_effect(effect); +} + +static void +lib_3a_AwbGetImageEffect(ia_3a_image_effect *effect) +{ + *effect = ci_adv_isp_get_image_effect(); + cam_lib_3a_dbg("%s:%d effect: %d\n", __func__, __LINE__); + +} void lib_3a_link_functions_init (GstV4l2MFLDAdvCI *mfldadvci) @@ -507,6 +523,8 @@ lib_3a_link_functions_init (GstV4l2MFLDAdvCI *mfldadvci) mfldadvci->AwbGetMode = lib_3a_AwbGetMode; mfldadvci->AwbSetLightSource = lib_3a_AwbSetLightSource; mfldadvci->AwbGetLightSource = lib_3a_AwbGetLightSource; + mfldadvci->AwbSetImageEffect = lib_3a_AwbSetImageEffect; + mfldadvci->AwbGetImageEffect = lib_3a_AwbGetImageEffect; mfldadvci->AeGetWindowsNum = lib_3a_AeGetWindowsNum; mfldadvci->AwbVersion = lib_3a_AwbVersion; diff --git a/gst-libs/atomisphal/gstv4l2mfldadvci.h b/gst-libs/atomisphal/gstv4l2mfldadvci.h index 0b7a5a9..24f053f 100644 --- a/gst-libs/atomisphal/gstv4l2mfldadvci.h +++ b/gst-libs/atomisphal/gstv4l2mfldadvci.h @@ -134,6 +134,11 @@ struct _GstV4l2MFLDAdvCI void (*AwbSetMode)(ia_3a_awb_mode mode); void (*AwbGetMode)(ia_3a_awb_mode *mode); + /* color tone */ + void (*AwbSetImageEffect) (ia_3a_image_effect effect); + void (*AwbGetImageEffect)(ia_3a_image_effect *effect); + + /* AWB Light Source */ void (*AwbSetLightSource)(ia_3a_awb_light_source ls); void (*AwbGetLightSource)(ia_3a_awb_light_source *ls); diff --git a/gst-libs/atomisphal/mfld_cam.c b/gst-libs/atomisphal/mfld_cam.c index d55572c..d2cfbd0 100644 --- a/gst-libs/atomisphal/mfld_cam.c +++ b/gst-libs/atomisphal/mfld_cam.c @@ -221,6 +221,9 @@ set_tone_mode (int fd, int mode) { cam_err_t ret = CAM_ERR_NONE; enum v4l2_colorfx colorfx = mode; + + cam_driver_dbg ("%s mode %d\n", __func__, mode); + ret = cam_driver_set_tone_mode (fd, colorfx); if (ret) mfld_cam_settings.tone_mode = mode; diff --git a/gst-libs/gst/camera/gstmfldcameracolorbalance.c b/gst-libs/gst/camera/gstmfldcameracolorbalance.c index 604cc89..a245408 100644 --- a/gst-libs/gst/camera/gstmfldcameracolorbalance.c +++ b/gst-libs/gst/camera/gstmfldcameracolorbalance.c @@ -88,6 +88,19 @@ gst_camerasrc_color_balance_set_value (GstCameraSrc * camerasrc, g_return_if_fail (gst_camerasrc_color_balance_contains_channel (camerasrc, camchannel)); + GST_OBJECT_LOCK (camerasrc); + switch (camchannel->id) { + case MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV: + camerasrc->photoconf.tone_mode = value; + break; + case MM_CAM_FILTER_WB_SOURCE_PRIV: + camerasrc->photoconf.wb_mode = value; + break; + default: + break; + } + GST_OBJECT_UNLOCK (camerasrc); + bclass->set_attribute (camerasrc, camchannel->id, value); } diff --git a/gst-libs/gst/camera/gstmfldcameracolorbalance.h b/gst-libs/gst/camera/gstmfldcameracolorbalance.h index ed42ea9..2c9f9f5 100644 --- a/gst-libs/gst/camera/gstmfldcameracolorbalance.h +++ b/gst-libs/gst/camera/gstmfldcameracolorbalance.h @@ -25,6 +25,7 @@ #ifndef __GST_CAMERA_SRC_COLOR_BALANCE_H__ #define __GST_CAMERA_SRC_COLOR_BALANCE_H__ +#include #include #include @@ -45,6 +46,48 @@ G_BEGIN_DECLS #define GST_IS_CAMERA_SRC_COLOR_BALANCE_CHANNEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CAMERA_SRC_COLOR_BALANCE_CHANNEL)) + +/* Keep standard v4l2 controls supported + * add own private control id's for tizen specific controls + * note rule below for priv control ids. + * #define V4L2_CID_PRIVATE_BASE 0x08000000 + */ +#define SOURCE_PRIV_BASE V4L2_CID_PRIVATE_BASE +#define MM_CAM_FILTER_WB_SOURCE_PRIV (SOURCE_PRIV_BASE + 1) +#define MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV (SOURCE_PRIV_BASE + 2) + +#define MM_CAM_SOURCE_PRIV_LAST MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV + +static struct v4l2_queryctrl mmfw_wb_controls[] = { + { + .id = MM_CAM_FILTER_WB_SOURCE_PRIV, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "white balance", + .minimum = 0x0, + .maximum = 0xffff, + .step = 0x01, + .default_value = 0x00, + .flags = 0, + }, + { + .id = MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "color tone", + .minimum = 0x0, + .maximum = 0xffff, + .step = 0x01, + .default_value = 0x00, + .flags = 0, + } +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#endif + +#define N_MMFW_CONTROLS (ARRAY_SIZE(mmfw_wb_controls)) + + typedef struct _GstCameraSrcColorBalanceChannel { GstColorBalanceChannel parent; diff --git a/gst/mfldv4l2cam/v4l2camsrc_calls.c b/gst/mfldv4l2cam/v4l2camsrc_calls.c index 0a84178..f8455a4 100644 --- a/gst/mfldv4l2cam/v4l2camsrc_calls.c +++ b/gst/mfldv4l2cam/v4l2camsrc_calls.c @@ -59,6 +59,34 @@ static const gint gst_v4l2camsrc_capture_map[] = { CAM_VIEWFINDER_MODE_VIDEO_RECORD, -1 }; + +static const gint gst_v4l2camsrc_effect_map[] = { + CAM_GENERAL_EFFECT_TYPE_NORMAL, + CAM_GENERAL_EFFECT_TYPE_SEPIA, + CAM_GENERAL_EFFECT_TYPE_NEGATIVE, + CAM_GENERAL_EFFECT_TYPE_GRAYSCALE, + CAM_GENERAL_EFFECT_TYPE_NORMAL, + CAM_GENERAL_EFFECT_TYPE_VIVID, + CAM_GENERAL_EFFECT_TYPE_NORMAL, + CAM_GENERAL_EFFECT_TYPE_NORMAL, + CAM_GENERAL_EFFECT_TYPE_NORMAL, + CAM_GENERAL_EFFECT_TYPE_SKY_BLUE, + CAM_GENERAL_EFFECT_TYPE_GRASS_GREEN, + CAM_GENERAL_EFFECT_TYPE_SKIN_WHITEN, + -1 +}; + +static const gint gst_v4l2camsrc_wb_map[] = { + CAM_AWB_MODE_AUTO, + CAM_AWB_MODE_DAYLIGHT, + CAM_AWB_MODE_SUNSET, + CAM_AWB_MODE_CLOUDY, + CAM_AWB_MODE_TUNGSTEN, + CAM_AWB_MODE_FLUORESCENT, + -1 +}; + + static gint find_item (const gint table[], const gint item); /* Define this to use memory locking for video buffers */ /* #define USE_MLOCK */ @@ -667,6 +695,23 @@ s_input_failed: return FALSE; } } + +static gboolean +get_supported_mmfw_control (GstMFLDV4l2CamSrc * v4l2camsrc, struct v4l2_queryctrl *control) +{ + int i; + GST_DEBUG_OBJECT (v4l2camsrc, "set private control (%x)", control->id); + + for (i = 0; i < N_MMFW_CONTROLS; i++) { + if (mmfw_wb_controls[i].id == control->id) { + *control = mmfw_wb_controls[i]; + return TRUE; + } + } + return FALSE; +} + + /****************************************************** * gst_v4l2camsrc_fill_lists(): * fill the lists of enumerations @@ -676,7 +721,6 @@ static gboolean gst_v4l2camsrc_fill_lists (GstMFLDV4l2CamSrc * v4l2camsrc) { gint n; - const gchar *color_tone_name = "color tone"; GST_DEBUG_OBJECT (v4l2camsrc, "getting enumerations"); GST_V4L2CAMSRC_CHECK_OPEN (v4l2camsrc); @@ -695,11 +739,19 @@ gst_v4l2camsrc_fill_lists (GstMFLDV4l2CamSrc * v4l2camsrc) n = V4L2_CID_PRIVATE_BASE; /* FIXME: We are still not handling private controls. We need a new GstInterface to export those controls */ - break; + //break; + GST_DEBUG_OBJECT (v4l2camsrc, "private ID"); } control.id = n; - if (ioctl (v4l2camsrc->video_fd, VIDIOC_QUERYCTRL, &control) < 0) { + + if( n > SOURCE_PRIV_BASE) { + if( n > MM_CAM_SOURCE_PRIV_LAST) + break; + else + get_supported_mmfw_control(v4l2camsrc, &control); + } + else if (ioctl (v4l2camsrc->video_fd, VIDIOC_QUERYCTRL, &control) < 0) { if (errno == EINVAL) { if (n < V4L2_CID_PRIVATE_BASE) /* continue so that we also check private controls */ @@ -733,6 +785,8 @@ gst_v4l2camsrc_fill_lists (GstMFLDV4l2CamSrc * v4l2camsrc) case V4L2_CID_AUTOGAIN: case V4L2_CID_GAIN: case V4L2_CID_COLORFX: + case MM_CAM_FILTER_WB_SOURCE_PRIV: + case MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV: /* we only handle these for now (why?) */ break; case V4L2_CID_HFLIP: @@ -769,13 +823,7 @@ gst_v4l2camsrc_fill_lists (GstMFLDV4l2CamSrc * v4l2camsrc) v4l2channel = g_object_new (GST_TYPE_CAMERA_SRC_COLOR_BALANCE_CHANNEL, NULL); channel = GST_COLOR_BALANCE_CHANNEL (v4l2channel); - // Samsung mmfw camcoder used color tone as a name for V4L2_CID_COLORFX - if (n == V4L2_CID_COLORFX) { - channel->label = g_strdup (color_tone_name); - GST_DEBUG_OBJECT (v4l2camsrc, "rename ControlID to %s (%x)", control.name, n); - } - else - channel->label = g_strdup ((const gchar *) control.name); + channel->label = g_strdup ((const gchar *) control.name); v4l2channel->id = n; @@ -955,6 +1003,8 @@ gst_v4l2camsrc_get_attribute (GstCameraSrc * camsrc, GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc); struct v4l2_control control; + cam_err_t err; + int tmp_value; GST_DEBUG_OBJECT (v4l2camsrc, "getting value of attribute %d", attribute_num); @@ -963,10 +1013,26 @@ gst_v4l2camsrc_get_attribute (GstCameraSrc * camsrc, control.id = attribute_num; - if (ioctl (v4l2camsrc->video_fd, VIDIOC_G_CTRL, &control) < 0) - goto ctrl_failed1; - - *value = control.value; + if (control.id > SOURCE_PRIV_BASE) { + GST_DEBUG_OBJECT (v4l2camsrc, "mmfw control JippiKayJei"); + switch (control.id) { + case MM_CAM_FILTER_WB_SOURCE_PRIV: + err = cam_feature_get (v4l2camsrc->video_fd, CAM_AWB_MODE, &tmp_value); + *value = find_item (gst_v4l2camsrc_wb_map, tmp_value); + break; + case MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV: + err = cam_feature_get (v4l2camsrc->video_fd, CAM_GENERAL_EFFECT_TYPE, &tmp_value); + *value = find_item (gst_v4l2camsrc_effect_map, tmp_value); + break; + default: + break; + } + } + else { + if (ioctl (v4l2camsrc->video_fd, VIDIOC_G_CTRL, &control) < 0) + goto ctrl_failed1; + *value = control.value; + } return TRUE; @@ -1010,7 +1076,7 @@ gst_v4l2camsrc_set_attribute (GstCameraSrc * camsrc, int attribute_num, const int value) { GstMFLDV4l2CamSrc *v4l2camsrc = GST_V4L2CAMSRC (camsrc); - + cam_err_t err; struct v4l2_control control; GST_DEBUG_OBJECT (v4l2camsrc, "setting value of attribute %d to %d", @@ -1021,9 +1087,24 @@ gst_v4l2camsrc_set_attribute (GstCameraSrc * camsrc, control.id = attribute_num; control.value = value; - if (ioctl (v4l2camsrc->video_fd, VIDIOC_S_CTRL, &control) < 0) - goto ctrl_failed1; + if (control.id > SOURCE_PRIV_BASE) { + GST_DEBUG_OBJECT (v4l2camsrc, "mmfw control JippiKayJei"); + switch (control.id) { + case MM_CAM_FILTER_WB_SOURCE_PRIV: + cam_feature_set (v4l2camsrc->video_fd, CAM_AWB_MODE, gst_v4l2camsrc_wb_map[value]); + break; + case MM_CAM_FILTER_COLOR_TONE_SOURCE_PRIV: + cam_feature_set (v4l2camsrc->video_fd, CAM_GENERAL_EFFECT_TYPE, gst_v4l2camsrc_effect_map[value]); + break; + default: + break; + } + } + else { + if (ioctl (v4l2camsrc->video_fd, VIDIOC_S_CTRL, &control) < 0) + goto ctrl_failed1; + } return TRUE; ctrl_failed1: @@ -2808,34 +2889,6 @@ gst_v4l2camsrc_update_cropping (GstMFLDV4l2CamSrc * v4l2camsrc, gint width, * Table value = Device/Implementation -specific setting value */ - - -static const gint gst_v4l2camsrc_wb_map[] = { - CAM_AWB_MODE_AUTO, - CAM_AWB_MODE_DAYLIGHT, - CAM_AWB_MODE_SUNSET, - CAM_AWB_MODE_CLOUDY, - CAM_AWB_MODE_TUNGSTEN, - CAM_AWB_MODE_FLUORESCENT, - -1 -}; - -static const gint gst_v4l2camsrc_effect_map[] = { - CAM_GENERAL_EFFECT_TYPE_NORMAL, - CAM_GENERAL_EFFECT_TYPE_SEPIA, - CAM_GENERAL_EFFECT_TYPE_NEGATIVE, - CAM_GENERAL_EFFECT_TYPE_GRAYSCALE, - CAM_GENERAL_EFFECT_TYPE_NORMAL, - CAM_GENERAL_EFFECT_TYPE_VIVID, - CAM_GENERAL_EFFECT_TYPE_NORMAL, - CAM_GENERAL_EFFECT_TYPE_NORMAL, - CAM_GENERAL_EFFECT_TYPE_NORMAL, - CAM_GENERAL_EFFECT_TYPE_SKY_BLUE, - CAM_GENERAL_EFFECT_TYPE_GRASS_GREEN, - CAM_GENERAL_EFFECT_TYPE_SKIN_WHITEN, - -1 -}; - static const gint gst_v4l2camsrc_scene_map_image[] = { 999, /* GST_PHOTOGRAPHY_SCENE_MODE_MANUAL */ CAM_GENERAL_SCENE_MODE_CLOSEUP, diff --git a/packaging/mfldv4l2camsrc.changes b/packaging/mfldv4l2camsrc.changes index 0b28d31..c5da20c 100644 --- a/packaging/mfldv4l2camsrc.changes +++ b/packaging/mfldv4l2camsrc.changes @@ -1,3 +1,6 @@ +* Thu Nov 15 2012 Marko Ollonen accepted/trunk/20121112.215039@f192b64 +- white bablance control added. + * Sat Nov 10 2012 Marko Ollonen accepted/trunk/20121106.174439@5af9475 - enable exposure configuration to camera control interface. diff --git a/packaging/mfldv4l2camsrc.spec b/packaging/mfldv4l2camsrc.spec index fbfa4fa..42ea365 100644 --- a/packaging/mfldv4l2camsrc.spec +++ b/packaging/mfldv4l2camsrc.spec @@ -1,6 +1,6 @@ Name: mfldv4l2camsrc Summary: Camera source component for Intel Medfield ISP -Version: 0.46 +Version: 0.47 Release: 1 Group: Applications/Multimedia License: LGPLv2+ -- 2.7.4