Support device capability provided by camera HAL 54/315454/7
authorJeongmo Yang <jm80.yang@samsung.com>
Tue, 16 Jul 2024 06:24:50 +0000 (15:24 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Wed, 7 Aug 2024 05:46:45 +0000 (14:46 +0900)
- Previously, libmm-camcorder uses only ini files from media-config package.
  But, it's proper for target which has fixed capability camera.
  (built-in or USB camera, but not changable.)
- The device capability from camera HAL does not support All functions,
  but, format, resolution and fps are supported only now.
- If camera HAL supports device capability, libmm-camcorder will update
  the related attributes after load ini files.

[Version] 1.2.0
[Issue Type] New feature

Change-Id: I9ba8302020b79271c3422f5dcda9e1ab2aedf7d4
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
configure.ac
packaging/libmm-camcorder.spec
src/Makefile.am
src/include/mm_camcorder_capability.h [new file with mode: 0644]
src/include/mm_camcorder_internal.h
src/mm_camcorder_attribute.c
src/mm_camcorder_capability.c [new file with mode: 0644]
src/mm_camcorder_configure.c
src/mm_camcorder_internal.c
src/mm_camcorder_platform.c

index cc398fb08fb385408c62329b09363ae3bb6d3e54..9f53fb7bc59da27a0fa8e5a56055677e04bde4b3 100644 (file)
@@ -184,6 +184,10 @@ PKG_CHECK_MODULES(DLOG, dlog)
 AC_SUBST(DLOG_CFLAGS)
 AC_SUBST(DLOG_LIBS)
 
+PKG_CHECK_MODULES(HAL_API_CAMERA, hal-api-camera)
+AC_SUBST(HAL_API_CAMERA_CFLAGS)
+AC_SUBST(HAL_API_CAMERA_LIBS)
+
 AC_ARG_ENABLE(product-tv, AC_HELP_STRING([--enable-product-tv],[enable tv defined code]),
 [
   case "${enableval}" in
index 317028ea18c5af7d90a6e577ef48a6adf934f40e..0d070560405c263814e46c6e520a74eae57bc702 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       libmm-camcorder
 Summary:    Camera and recorder library
-Version:    1.1.3
+Version:    1.2.0
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
@@ -39,6 +39,7 @@ BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(dpm)
 BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(hal-api-camera)
 %if "%{gtests}" == "1"
 BuildRequires:  pkgconfig(gmock)
 %endif
index b4ff0d734845f2fa8e3ca27d128b4b0ad1713ce5..bc1bde9b3967b1722e6c89da5d1aea1ba8e108cd 100644 (file)
@@ -12,6 +12,7 @@ noinst_HEADERS = include/mm_camcorder_audiorec.h \
                 include/mm_camcorder_gstcommon.h \
                 include/mm_camcorder_internal.h \
                 include/mm_camcorder_platform.h \
+                include/mm_camcorder_capability.h \
                 include/mm_camcorder_stillshot.h \
                 include/mm_camcorder_videorec.h \
                 include/mm_camcorder_util.h \
@@ -30,6 +31,7 @@ libmmfcamcorder_la_SOURCES = mm_camcorder.c \
                             mm_camcorder_audiorec.c \
                             mm_camcorder_gstcommon.c \
                             mm_camcorder_platform.c \
+                            mm_camcorder_capability.c \
                             mm_camcorder_configure.c \
                             mm_camcorder_util.c \
                             mm_camcorder_exifinfo.c \
@@ -58,6 +60,7 @@ libmmfcamcorder_la_CFLAGS = -I$(srcdir)/include \
                             $(TTRACE_CFLAGS) \
                             $(DPM_CFLAGS) \
                             $(DLOG_CFLAGS) \
+                            $(HAL_API_CAMERA_CFLAGS) \
                             $(SYSTEMINFO_CFLAGS)
 
 libmmfcamcorder_la_LIBADD = \
@@ -77,6 +80,7 @@ libmmfcamcorder_la_LIBADD = \
                            $(TTRACE_LIBS) \
                            $(DPM_LIBS) \
                            $(DLOG_LIBS) \
+                           $(HAL_API_CAMERA_LIBS) \
                            $(STORAGE_LIBS)
 
 libmmfcamcorder_la_CFLAGS += -D_FILE_OFFSET_BITS=64
diff --git a/src/include/mm_camcorder_capability.h b/src/include/mm_camcorder_capability.h
new file mode 100644 (file)
index 0000000..1c6fa71
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * libmm-camcorder
+ *
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MM_CAMCORDER_CAPABILITY_H__
+#define __MM_CAMCORDER_CAPABILITY_H__
+
+/*=======================================================================================
+| INCLUDE FILES                                                                         |
+=======================================================================================*/
+#include <hal-camera.h>
+#include <mm_types.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=======================================================================================
+| GLOBAL DEFINITIONS AND DECLARATIONS FOR CAMCORDER                                     |
+=======================================================================================*/
+
+
+/*=======================================================================================
+| MACRO DEFINITIONS                                                                     |
+=======================================================================================*/
+
+
+/*=======================================================================================
+| ENUM DEFINITIONS                                                                      |
+=======================================================================================*/
+
+
+/*=======================================================================================
+| STRUCTURE DEFINITIONS                                                                 |
+=======================================================================================*/
+typedef struct _mmcam_device_capability_s {
+       void *hal_handle;
+       camera_device_capability_list_s list;
+       camera_device_capability_s *current_capability;
+       camera_device_capability_format_s *current_format;
+       camera_device_capability_resolution_s *current_resolution;
+} mmcam_device_capability_s;
+
+
+/*=======================================================================================
+| CONSTANT DEFINITIONS                                                                  |
+=======================================================================================*/
+
+
+/*=======================================================================================
+| STATIC VARIABLES                                                                      |
+=======================================================================================*/
+
+
+/*=======================================================================================
+| EXTERN GLOBAL VARIABLE                                                                |
+=======================================================================================*/
+
+/*=======================================================================================
+| GLOBAL FUNCTION PROTOTYPES                                                            |
+=======================================================================================*/
+int _mmcamcorder_capability_init(MMHandleType handle);
+int _mmcamcorder_capability_deinit(MMHandleType handle);
+
+int _mmcamcorder_capability_update_capability_format(MMHandleType handle, MMPixelFormatType mm_format);
+int _mmcamcorder_capability_update_capability_resolution(MMHandleType handle, int width, int height);
+
+int _mmcamcorder_capability_update_preview_format_list(MMHandleType handle);
+int _mmcamcorder_capability_update_preview_resolution_list(MMHandleType handle);
+int _mmcamcorder_capability_update_preview_fps(MMHandleType handle);
+
+int _mmcamcorder_capability_get_preview_fps_list_by_resolution(MMHandleType handle,
+       int width, int height, int **fps_list, int *count, int *default_fps);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_CAMCORDER_CAPABILITY_H__ */
index c7706e19efbed2ea5b093ba0de981ef5feb7d585..cddea0311f60ffec676601fdf2189894e9e6064f 100644 (file)
@@ -53,6 +53,7 @@
 #include "mm_camcorder_util.h"
 #include "mm_camcorder_configure.h"
 #include "mm_camcorder_sound.h"
+#include "mm_camcorder_capability.h"
 
 #ifdef _MMCAMCORDER_RM_SUPPORT
 /* rm (resource manager)*/
@@ -776,6 +777,10 @@ typedef struct mmf_camcorder {
 #endif /* _MMCAMCORDER_RM_SUPPORT */
        SOUND_INFO snd_info;                   /**< Sound handle for multishot capture */
 
+       /* device capability */
+       mmcam_device_capability_s *mmcam_capability;            /**< Camera device capability */
+       gboolean on_preview_resolution_update;
+
        /* callback handlers */
        MMMessageCallback msg_cb;                               /**< message callback */
        void *msg_cb_param;                                     /**< message callback parameter */
@@ -797,6 +802,7 @@ typedef struct mmf_camcorder {
        conf_info_table *conf_ctrl_info_table[CONFIGURE_CATEGORY_CTRL_NUM]; /** configure info table - CONTROL category */
        int conf_main_category_size[CONFIGURE_CATEGORY_MAIN_NUM]; /** configure info table size - MAIN category */
        int conf_ctrl_category_size[CONFIGURE_CATEGORY_CTRL_NUM]; /** configure info table size - CONTROL category */
+       gboolean is_configured;                                 /**< Flag for configure completion */
        _MMCamcorderMTSafe mtsafe;                              /**< Thread safe */
        int state_change_by_system;                             /**< MSL changes its state by itself because of system */
        GMutex restart_preview_lock;                            /**< Capture sound mutex */
index 62799d79171721afa7b49b5318c376a282eb13b2..74ba10b42db16dc3555d56d7f0ad12582cb77868 100644 (file)
@@ -1944,6 +1944,8 @@ _mmcamcorder_set_attributes(MMHandleType handle, char **err_attr_name, const cha
                return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
        }
 
+       hcamcorder->error_code = MM_ERROR_NONE;
+
        /* copy var_args to keep original var_args */
        va_copy(var_args_copy, var_args);
 
@@ -1956,7 +1958,6 @@ _mmcamcorder_set_attributes(MMHandleType handle, char **err_attr_name, const cha
        }
 
        if (ret == MM_ERROR_NONE) {
-               hcamcorder->error_code = MM_ERROR_NONE;
                /* In 64bit environment, unexpected result is returned if var_args is used again. */
                ret = mm_attrs_set_valist(attrs, &tmp_err_attr_name, attribute_name, var_args_copy);
        }
@@ -2354,8 +2355,9 @@ bool _mmcamcorder_commit_audio_volume(MMHandleType handle, int attr_idx, const M
 
 bool _mmcamcorder_commit_camera_format(MMHandleType handle, int attr_idx, const MMAttrsValue *value)
 {
-       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+       int ret = MM_ERROR_NONE;
        int current_state = MM_CAMCORDER_STATE_NONE;
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
 
        mmf_return_val_if_fail(hcamcorder && value, FALSE);
 
@@ -2366,6 +2368,22 @@ bool _mmcamcorder_commit_camera_format(MMHandleType handle, int attr_idx, const
                return FALSE;
        }
 
+       if (hcamcorder->is_configured && hcamcorder->mmcam_capability) {
+               ret = _mmcamcorder_capability_update_capability_format(handle, value->value.i_val);
+               if (ret != MM_ERROR_NONE) {
+                       MMCAM_LOG_ERROR("update capability format failed[0x%x]", ret);
+                       return FALSE;
+               }
+
+               ret = _mmcamcorder_capability_update_preview_resolution_list(handle);
+               if (ret != MM_ERROR_NONE) {
+                       MMCAM_LOG_ERROR("update resolution list failed[0x%x]", ret);
+                       return FALSE;
+               }
+       }
+
+       MMCAM_LOG_INFO("done");
+
        return TRUE;
 }
 
@@ -2394,6 +2412,11 @@ bool _mmcamcorder_commit_camera_fps(MMHandleType handle, int attr_idx, const MMA
 
        MMCAM_LOG_INFO("FPS(%d)", value->value.i_val);
 
+       if (hcamcorder->on_preview_resolution_update) {
+               MMCAM_LOG_INFO("no need to check FPS list");
+               return TRUE;
+       }
+
        ret = mm_camcorder_get_attributes(handle, NULL,
                MMCAM_CAMERA_WIDTH, &resolution_width,
                MMCAM_CAMERA_HEIGHT, &resolution_height,
@@ -2557,20 +2580,25 @@ bool _mmcamcorder_commit_camera_width(MMHandleType handle, int attr_idx, const M
 
 bool _mmcamcorder_commit_camera_height(MMHandleType handle, int attr_idx, const MMAttrsValue *value)
 {
-       int ret = 0;
+       bool ret = false;
+       int mm_ret = MM_ERROR_NONE;
        int current_state = MM_CAMCORDER_STATE_NONE;
+       int width = 0;
+       int height = 0;
+       int preview_format = MM_PIXEL_FORMAT_NV12;
+       int codec_type = MM_IMAGE_CODEC_JPEG;
        MMHandleType attr = 0;
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
        _MMCamcorderSubContext *sc = NULL;
 
-       mmf_return_val_if_fail(hcamcorder && value, FALSE);
+       mmf_return_val_if_fail(hcamcorder && value, false);
 
        sc = MMF_CAMCORDER_SUBCONTEXT(handle);
        if (!sc)
-               return TRUE;
+               return true;
 
        attr = MMF_CAMCORDER_ATTRS(hcamcorder);
-       mmf_return_val_if_fail(attr, FALSE);
+       mmf_return_val_if_fail(attr, false);
 
        MMCAM_LOG_INFO("Height(%d)", value->value.i_val);
        current_state = _mmcamcorder_get_state(handle);
@@ -2578,77 +2606,88 @@ bool _mmcamcorder_commit_camera_height(MMHandleType handle, int attr_idx, const
        if (current_state > MM_CAMCORDER_STATE_PREPARE) {
                MMCAM_LOG_INFO("Resolution can't be changed.(state=%d)", current_state);
                hcamcorder->error_code = MM_ERROR_CAMCORDER_INVALID_STATE;
-               return FALSE;
-       } else {
-               int width = 0;
-               int height = value->value.i_val;
-               int preview_format = MM_PIXEL_FORMAT_NV12;
-               int codec_type = MM_IMAGE_CODEC_JPEG;
-               int video_stabilization = 0;
-
-               mm_camcorder_get_attributes(handle, NULL,
-                       MMCAM_CAMERA_WIDTH, &width,
-                       MMCAM_CAMERA_FORMAT, &preview_format,
-                       MMCAM_IMAGE_ENCODER, &codec_type,
-                       MMCAM_CAMERA_VIDEO_STABILIZATION, &video_stabilization,
-                       NULL);
+               return false;
+       }
 
-               sc->info_video->preview_width = width;
-               sc->info_video->preview_height = height;
+       height = value->value.i_val;
 
-               if (current_state == MM_CAMCORDER_STATE_PREPARE) {
-                       if (hcamcorder->resolution_changed == FALSE) {
-                               MMCAM_LOG_INFO("no need to restart preview");
-                               return TRUE;
-                       }
+       mm_ret = mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_CAMERA_WIDTH, &width,
+               MMCAM_CAMERA_FORMAT, &preview_format,
+               MMCAM_IMAGE_ENCODER, &codec_type,
+               NULL);
+       if (mm_ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("attributes get failed[0x%x]", ret);
+               return false;
+       }
 
-                       hcamcorder->resolution_changed = FALSE;
+       sc->info_video->preview_width = width;
+       sc->info_video->preview_height = height;
 
-                       if (g_mutex_trylock(&hcamcorder->restart_preview_lock)) {
-                               MMCAM_LOG_INFO("restart preview");
+       /* update FPS from capability */
+       if (hcamcorder->is_configured && hcamcorder->mmcam_capability) {
+               mm_ret = _mmcamcorder_capability_update_capability_resolution(handle, width, height);
+               if (mm_ret != MM_ERROR_NONE) {
+                       MMCAM_LOG_ERROR("update capability resolution failed[0x%x]", mm_ret);
+                       return false;
+               }
 
-                               MMCAM_LOG_INFO("set empty buffers");
+               hcamcorder->on_preview_resolution_update = TRUE;
+               mm_ret = _mmcamcorder_capability_update_preview_fps(hcamcorder);
+               hcamcorder->on_preview_resolution_update = FALSE;
 
-                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
-                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
+               if (mm_ret != MM_ERROR_NONE) {
+                       MMCAM_LOG_ERROR("update resolution list failed[0x%x]", mm_ret);
+                       return false;
+               }
+       }
 
-                               if (!_mmcamcorder_is_encoded_preview_pixel_format(preview_format))
-                                       _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_READY);
+       if (current_state != MM_CAMCORDER_STATE_PREPARE) {
+               sc->info_image->preview_format = preview_format;
+               sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codec_type, hcamcorder->use_zero_copy_format);
+               return _mmcamcorder_set_camera_resolution(handle, width, height);
+       }
 
-                               /* check decoder recreation */
-                               if (!_mmcamcorder_recreate_decoder_for_encoded_preview(handle)) {
-                                       MMCAM_LOG_ERROR("_mmcamcorder_recreate_decoder_for_encoded_preview failed");
-                                       g_mutex_unlock(&hcamcorder->restart_preview_lock);
-                                       return FALSE;
-                               }
+       if (hcamcorder->resolution_changed == FALSE) {
+               MMCAM_LOG_INFO("no need to restart preview");
+               return true;
+       }
 
-                               /* get preview format */
-                               sc->info_image->preview_format = preview_format;
-                               sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codec_type, hcamcorder->use_zero_copy_format);
+       hcamcorder->resolution_changed = FALSE;
 
-                               ret = _mmcamcorder_set_camera_resolution(handle, width, height);
+       if (!g_mutex_trylock(&hcamcorder->restart_preview_lock)) {
+               MMCAM_LOG_ERROR("currently locked for preview restart");
+               return false;
+       }
 
-                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
-                               MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
+       MMCAM_LOG_INFO("restart preview");
 
-                               if (!_mmcamcorder_is_encoded_preview_pixel_format(preview_format))
-                                       _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_PLAYING);
+       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
+       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
 
-                               /* unlock */
-                               g_mutex_unlock(&hcamcorder->restart_preview_lock);
-                       } else {
-                               MMCAM_LOG_ERROR("currently locked for preview restart");
-                               return FALSE;
-                       }
-               } else {
-                       /* get preview format */
-                       sc->info_image->preview_format = preview_format;
-                       sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codec_type, hcamcorder->use_zero_copy_format);
-                       ret = _mmcamcorder_set_camera_resolution(handle, width, height);
-               }
+       if (!_mmcamcorder_is_encoded_preview_pixel_format(preview_format))
+               _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_READY);
 
-               return ret;
+       if (!_mmcamcorder_recreate_decoder_for_encoded_preview(handle)) {
+               MMCAM_LOG_ERROR("_mmcamcorder_recreate_decoder_for_encoded_preview failed");
+               g_mutex_unlock(&hcamcorder->restart_preview_lock);
+               return false;
        }
+
+       sc->info_image->preview_format = preview_format;
+       sc->fourcc = _mmcamcorder_get_fourcc(sc->info_image->preview_format, codec_type, hcamcorder->use_zero_copy_format);
+
+       ret = _mmcamcorder_set_camera_resolution(handle, width, height);
+
+       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
+       MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
+
+       if (!_mmcamcorder_is_encoded_preview_pixel_format(preview_format))
+               _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_PLAYING);
+
+       g_mutex_unlock(&hcamcorder->restart_preview_lock);
+
+       return ret;
 }
 
 
@@ -5296,7 +5335,7 @@ static int __mmcamcorder_check_valid_pair(MMHandleType handle, char **err_attr_n
                                        }
                                }
 
-                               return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
+                               return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
                        }
 
                        if (!strcmp(check_pair_name[i][0], MMCAM_CAMERA_WIDTH)) {
diff --git a/src/mm_camcorder_capability.c b/src/mm_camcorder_capability.c
new file mode 100644 (file)
index 0000000..bb44ebb
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * libmm-camcorder
+ *
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*=======================================================================================
+| INCLUDE FILES                                                                         |
+=======================================================================================*/
+#include "mm_camcorder_internal.h"
+
+/*---------------------------------------------------------------------------------------
+| GLOBAL VARIABLE DEFINITIONS                                                           |
+---------------------------------------------------------------------------------------*/
+#define CAPABILITY_INDEX_INVALID        -1
+#define CONFIGURE_FPS_ARRAY_NAME_MAX    8
+
+static const char *g_format_string_table[MM_PIXEL_FORMAT_NUM] = {
+       [MM_PIXEL_FORMAT_NV12]          = "NV12",
+       [MM_PIXEL_FORMAT_NV21]          = "NV21",
+       [MM_PIXEL_FORMAT_I420]          = "I420",
+       [MM_PIXEL_FORMAT_YV12]          = "YV12",
+       [MM_PIXEL_FORMAT_YUYV]          = "YUYV",
+       [MM_PIXEL_FORMAT_UYVY]          = "UYVY",
+       [MM_PIXEL_FORMAT_ENCODED]       = "JPEG",
+       [MM_PIXEL_FORMAT_ENCODED_H264]  = "H264",
+       [MM_PIXEL_FORMAT_ENCODED_MJPEG] = "MJPEG",
+       [MM_PIXEL_FORMAT_ENCODED_VP8]   = "VP8",
+       [MM_PIXEL_FORMAT_ENCODED_VP9]   = "VP9",
+       [MM_PIXEL_FORMAT_INVZ]          = "INVZ"
+};
+
+static const MMPixelFormatType g_format_convert_table[CAMERA_PIXEL_FORMAT_MAX] = {
+       [CAMERA_PIXEL_FORMAT_NV12]  = MM_PIXEL_FORMAT_NV12,
+       [CAMERA_PIXEL_FORMAT_NV21]  = MM_PIXEL_FORMAT_NV21,
+       [CAMERA_PIXEL_FORMAT_I420]  = MM_PIXEL_FORMAT_I420,
+       [CAMERA_PIXEL_FORMAT_YV12]  = MM_PIXEL_FORMAT_YV12,
+       [CAMERA_PIXEL_FORMAT_YUYV]  = MM_PIXEL_FORMAT_YUYV,
+       [CAMERA_PIXEL_FORMAT_UYVY]  = MM_PIXEL_FORMAT_UYVY,
+       [CAMERA_PIXEL_FORMAT_JPEG]  = MM_PIXEL_FORMAT_ENCODED,
+       [CAMERA_PIXEL_FORMAT_H264]  = MM_PIXEL_FORMAT_ENCODED_H264,
+       [CAMERA_PIXEL_FORMAT_MJPEG] = MM_PIXEL_FORMAT_ENCODED_MJPEG,
+       [CAMERA_PIXEL_FORMAT_VP8]   = MM_PIXEL_FORMAT_ENCODED_VP8,
+       [CAMERA_PIXEL_FORMAT_VP9]   = MM_PIXEL_FORMAT_ENCODED_VP9,
+       [CAMERA_PIXEL_FORMAT_DEPTH] = MM_PIXEL_FORMAT_INVZ
+};
+
+
+static int __mmcamcorder_capability_update_attribute_int_array(MMHandleType attrs,
+       const char *attribute_name, int *new_list, int new_size,
+       int new_default, gboolean update_default)
+{
+       int ret = MM_ERROR_NONE;
+       int attribute_index = 0;
+
+       mmf_return_val_if_fail(attrs, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+       mmf_return_val_if_fail(attribute_name, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+       mmf_return_val_if_fail(new_list, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+       ret = mm_attrs_get_index(attrs, attribute_name, &attribute_index);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("[%s] get index failed[0x%x]", attribute_name, ret);
+               return ret;
+       }
+
+       MMCAM_LOG_WARNING("[%s], size[%d], default[%d], update default[%d]",
+               attribute_name, new_size, new_default, update_default);
+
+       ret = mm_attrs_set_valid_array(attrs, attribute_index,
+               new_list, new_size, new_default);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("[%s] set new list failed[0x%x]", attribute_name, ret);
+               return ret;
+       }
+
+       if (!update_default)
+               return MM_ERROR_NONE;
+
+       MMCAM_LOG_WARNING("[%s] update new default[%d]", attribute_name, new_default);
+
+       ret = mm_attrs_set_int(attrs, attribute_index, new_default);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("[%s] set new default[%d] failed[0x%x]",
+                       attribute_name, new_default, ret);
+               return ret;
+       }
+
+       ret = mm_attrs_commit(attrs, attribute_index);
+
+       MMCAM_LOG_WARNING("done[0x%x]", ret);
+
+       return ret;
+}
+
+
+static camera_device_capability_s *__mmcamcorder_capability_get_capability(mmcam_device_capability_s *mmcam_capability, int device_index)
+{
+       mmf_return_val_if_fail(mmcam_capability, NULL);
+
+       if (device_index >= mmcam_capability->list.device_count) {
+               MMCAM_LOG_ERROR("invalid device index[%d] vs device count[%d]",
+                       device_index, mmcam_capability->list.device_count);
+               return NULL;
+       }
+
+       if (!mmcam_capability->list.capability[device_index]) {
+               MMCAM_LOG_ERROR("NULL capability for device index[%d]", device_index);
+               return NULL;
+       }
+
+       mmcam_capability->current_capability = mmcam_capability->list.capability[device_index];
+
+       MMCAM_LOG_INFO("device[%d] capability[%p]", device_index, mmcam_capability->current_capability);
+
+       return mmcam_capability->current_capability;
+}
+
+
+static void __mmcamcorder_capability_dump(mmcam_device_capability_s *mmcam_capability)
+{
+       int device_index = 0;
+       int format_index = 0;
+       int resolution_index = 0;
+       int fps_index = 0;
+       camera_device_capability_s *_capability = NULL;
+       camera_device_capability_format_s *_format = NULL;
+       camera_device_capability_resolution_s *_resolution = NULL;
+
+       mmf_return_if_fail(mmcam_capability);
+
+       for (device_index = 0 ; device_index < mmcam_capability->list.device_count ; device_index++) {
+               _capability = mmcam_capability->list.capability[device_index];
+               if (!_capability) {
+                       MMCAM_LOG_WARNING("NULL capability[i:%d]", device_index);
+                       continue;
+               }
+
+               MMCAM_LOG_DEBUG("device[%02d] format count[%d]", device_index, _capability->format_count);
+
+               for (format_index = 0 ; format_index < _capability->format_count ; format_index++) {
+                       _format = _capability->format[format_index];
+                       if (!_format) {
+                               MMCAM_LOG_WARNING("  NULL format[i:%d]", format_index);
+                               continue;
+                       }
+
+                       MMCAM_LOG_DEBUG("  format[%02d] %d, resolution count[%d]", format_index,
+                               _format->pixel_format, _format->resolution_count);
+
+                       for (resolution_index = 0 ; resolution_index < _format->resolution_count ; resolution_index++) {
+                               _resolution = _format->resolution[resolution_index];
+                               if (!_resolution) {
+                                       MMCAM_LOG_WARNING("    NULL resolution[i:%d]", resolution_index);
+                                       continue;
+                               }
+
+                               MMCAM_LOG_DEBUG("    resolution[%02d] %04d x %04d, fps count[%d]", resolution_index,
+                                       _resolution->width, _resolution->height, _resolution->fps_list.count);
+
+                               for (fps_index = 0 ; fps_index < _resolution->fps_list.count ; fps_index++) {
+                                       MMCAM_LOG_DEBUG("      fps[%02d] %d", fps_index,
+                                               _resolution->fps_list.fps[fps_index]);
+                               }
+                       }
+               }
+       }
+}
+
+
+int _mmcamcorder_capability_init(MMHandleType handle)
+{
+       int ret = CAMERA_ERROR_NONE;
+       g_autofree mmcam_device_capability_s *new_mmcam_capability = NULL;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       new_mmcam_capability = g_new0(mmcam_device_capability_s, 1);
+
+       ret = hal_camera_init(NULL, &new_mmcam_capability->hal_handle);
+       if (ret != CAMERA_ERROR_NONE) {
+               MMCAM_LOG_WARNING("hal_camera_init failed[0x%x]", ret);
+               return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
+       }
+
+       ret = hal_camera_get_device_capability_list(new_mmcam_capability->hal_handle, &new_mmcam_capability->list);
+       if (ret != CAMERA_ERROR_NONE) {
+               MMCAM_LOG_WARNING("failed to get capability from camera HAL");
+
+               if (hal_camera_deinit(new_mmcam_capability->hal_handle) != CAMERA_ERROR_NONE)
+                       MMCAM_LOG_WARNING("failed to deinit HAL handle");
+
+               return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
+       }
+
+       __mmcamcorder_capability_dump(new_mmcam_capability);
+
+       hcamcorder->mmcam_capability = g_steal_pointer(&new_mmcam_capability);
+
+       return MM_ERROR_NONE;
+}
+
+
+int _mmcamcorder_capability_deinit(MMHandleType handle)
+{
+       int ret = CAMERA_ERROR_NONE;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_NONE);
+
+       ret = hal_camera_deinit(hcamcorder->mmcam_capability->hal_handle);
+       if (ret != CAMERA_ERROR_NONE)
+               MMCAM_LOG_WARNING("failed to deinit HAL handle[0x%x]", ret);
+
+       MMCAM_LOG_INFO("handle[%p], capability[%p]", hcamcorder, hcamcorder->mmcam_capability);
+
+       g_free(hcamcorder->mmcam_capability);
+       hcamcorder->mmcam_capability = NULL;
+
+       return MM_ERROR_NONE;
+}
+
+
+int _mmcamcorder_capability_update_capability_format(MMHandleType handle, MMPixelFormatType mm_format)
+{
+       int index = 0;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       camera_device_capability_s *_capability = NULL;
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+
+       _capability = hcamcorder->mmcam_capability->current_capability;
+
+       mmf_return_val_if_fail(_capability, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       MMCAM_LOG_INFO("update capability format for [%s]", g_format_string_table[mm_format]);
+
+       for (index = 0 ; index < _capability->format_count ; index++) {
+               camera_device_capability_format_s *_format = _capability->format[index];
+
+               if (!_format)
+                       continue;
+
+               if (mm_format == g_format_convert_table[_format->pixel_format]) {
+                       hcamcorder->mmcam_capability->current_format = _format;
+
+                       MMCAM_LOG_INFO("found capability format[%p] for [%s]",
+                               _format, g_format_string_table[mm_format]);
+
+                       return MM_ERROR_NONE;
+               }
+       }
+
+       MMCAM_LOG_ERROR("capability format not found for [%s]", g_format_string_table[mm_format]);
+
+       return MM_ERROR_CAMCORDER_INTERNAL;
+}
+
+
+int _mmcamcorder_capability_update_capability_resolution(MMHandleType handle, int width, int height)
+{
+       int index = 0;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       camera_device_capability_format_s *_format = NULL;
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+
+       _format = hcamcorder->mmcam_capability->current_format;
+
+       mmf_return_val_if_fail(_format, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       for (index = 0 ; index < _format->resolution_count ; index++) {
+               camera_device_capability_resolution_s *_resolution = _format->resolution[index];
+
+               if (!_resolution)
+                       continue;
+
+               if (_resolution->width == width && _resolution->height == height) {
+                       hcamcorder->mmcam_capability->current_resolution = _resolution;
+
+                       MMCAM_LOG_INFO("found capability resolution[%p] for [%d x %d]",
+                               _resolution, width, height);
+
+                       return MM_ERROR_NONE;
+               }
+       }
+
+       MMCAM_LOG_ERROR("capability resolution not found for [%d x %d]", width, height);
+
+       return MM_ERROR_CAMCORDER_INTERNAL;
+}
+
+
+int _mmcamcorder_capability_update_preview_format_list(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       int format_index = 0;
+       int format_count = 0;
+       int format_list[MM_PIXEL_FORMAT_NUM] = {0, };
+       gboolean is_current_supported = FALSE;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+       MMPixelFormatType default_mm_format = MM_PIXEL_FORMAT_INVALID;
+       MMPixelFormatType current_mm_format = MM_PIXEL_FORMAT_INVALID;
+
+       camera_device_capability_s *_capability = NULL;
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       _capability = __mmcamcorder_capability_get_capability(hcamcorder->mmcam_capability, hcamcorder->device_type);
+
+       mmf_return_val_if_fail(_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+
+       MMCAM_LOG_INFO("device[%d], capability format count[%d]",
+               hcamcorder->device_type, _capability->format_count);
+
+       ret = mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_CAMERA_FORMAT, &current_mm_format,
+               NULL);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("get current format failed[0x%x]", ret);
+               return ret;
+       }
+
+       format_index = format_count = 0;
+       for ( ; format_index < _capability->format_count ; format_index++) {
+               MMPixelFormatType converted_mm_format = MM_PIXEL_FORMAT_INVALID;
+               camera_device_capability_format_s *_format = _capability->format[format_index];
+
+               if (!_format)
+                       continue;
+
+               /* get converted MM format list */
+               converted_mm_format = g_format_convert_table[_format->pixel_format];
+
+               MMCAM_LOG_INFO("MM format list [i:%2d] [%s]",
+                       format_count, g_format_string_table[converted_mm_format]);
+
+               format_list[format_count] = converted_mm_format;
+               format_count++;
+
+               /* check whether current format is supported or not */
+               if (!is_current_supported && converted_mm_format == current_mm_format) {
+                       is_current_supported = TRUE;
+
+                       MMCAM_LOG_INFO("current format [%s] is supported",
+                               g_format_string_table[converted_mm_format]);
+               }
+
+               /* get default MM format */
+               if (_capability->default_format_index == format_index) {
+                       default_mm_format = converted_mm_format;
+
+                       MMCAM_LOG_INFO("default format [%s] from capability",
+                               g_format_string_table[converted_mm_format]);
+               }
+       }
+
+       if (!is_current_supported && default_mm_format == MM_PIXEL_FORMAT_INVALID) {
+               MMCAM_LOG_ERROR("update format failed [count:%d, default index:%d]",
+                       _capability->format_count, _capability->default_format_index);
+               return MM_ERROR_CAMCORDER_INTERNAL;
+       }
+
+       MMCAM_LOG_INFO("new MM format count[%d]", format_count);
+
+       ret = __mmcamcorder_capability_update_attribute_int_array(MMF_CAMCORDER_ATTRS(hcamcorder),
+               MMCAM_CAMERA_FORMAT, format_list, format_count,
+               default_mm_format, !is_current_supported);
+       if (ret != MM_ERROR_NONE)
+               return ret;
+
+       ret = _mmcamcorder_capability_update_capability_format(handle,
+               is_current_supported ? current_mm_format : default_mm_format);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("update capability format failed[0x%x]", ret);
+               return ret;
+       }
+
+       MMCAM_LOG_INFO("done");
+
+       return _mmcamcorder_capability_update_preview_resolution_list(handle);
+}
+
+
+int _mmcamcorder_capability_update_preview_resolution_list(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       int resolution_index = 0;
+       int update_index = CAPABILITY_INDEX_INVALID;
+       int default_index = CAPABILITY_INDEX_INVALID;
+       int width_list[RESOLUTION_COUNT_MAX] = {0, };
+       int height_list[RESOLUTION_COUNT_MAX] = {0, };
+       int current_width = 0;
+       int current_height = 0;
+       int default_width = 0;
+       int default_height = 0;
+       gboolean is_current_supported = FALSE;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+       camera_device_capability_format_s *_format = NULL;
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+
+       _format = hcamcorder->mmcam_capability->current_format;
+
+       mmf_return_val_if_fail(_format, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+       ret = mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_CAMERA_WIDTH, &current_width,
+               MMCAM_CAMERA_HEIGHT, &current_height,
+               NULL);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("get resolution failed[0x%x]", ret);
+               return ret;
+       }
+
+       default_index = _format->default_resolution_index;
+
+       for (resolution_index = 0 ; resolution_index < _format->resolution_count ; resolution_index++) {
+               width_list[resolution_index] = _format->resolution[resolution_index]->width;
+               height_list[resolution_index] = _format->resolution[resolution_index]->height;
+
+               MMCAM_LOG_INFO("resolution [i:%02d] [%d x %d]",
+                       resolution_index, width_list[resolution_index], height_list[resolution_index]);
+
+               if (!is_current_supported &&
+                       current_width == width_list[resolution_index] &&
+                       current_height == height_list[resolution_index]) {
+                       is_current_supported = TRUE;
+                       update_index = resolution_index;
+
+                       MMCAM_LOG_INFO("current resolution[%d x %d] is supported [i:%d]",
+                               current_width, current_height, resolution_index);
+               }
+       }
+
+       if (update_index == CAPABILITY_INDEX_INVALID) {
+               update_index = default_index;
+               MMCAM_LOG_WARNING("use default index[%d]", update_index);
+       }
+
+       default_width = _format->resolution[default_index]->width;
+       default_height = _format->resolution[default_index]->height;
+
+       MMCAM_LOG_INFO("new resolution count[%d], update[%d x %d, supported:%d], default[%d x %d]",
+               _format->resolution_count,
+               current_width, current_height, is_current_supported,
+               default_width, default_height);
+
+       ret = __mmcamcorder_capability_update_attribute_int_array(MMF_CAMCORDER_ATTRS(hcamcorder),
+               MMCAM_CAMERA_WIDTH, width_list, _format->resolution_count,
+               default_width, !is_current_supported);
+
+       ret |= __mmcamcorder_capability_update_attribute_int_array(MMF_CAMCORDER_ATTRS(hcamcorder),
+               MMCAM_CAMERA_HEIGHT, height_list, _format->resolution_count,
+               default_height, !is_current_supported);
+
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("update attribute for preview resolution failed[0x%x]", ret);
+               return ret;
+       }
+
+       ret = _mmcamcorder_capability_update_capability_resolution(handle,
+               is_current_supported ? current_width : default_width,
+               is_current_supported ? current_height : default_height);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("update capability resolution failed[0x%x]", ret);
+               return ret;
+       }
+
+       MMCAM_LOG_INFO("done");
+
+       return _mmcamcorder_capability_update_preview_fps(handle);
+}
+
+
+int _mmcamcorder_capability_update_preview_fps(MMHandleType handle)
+{
+       int ret = MM_ERROR_NONE;
+       int fps_index = 0;
+       int fps = 0;
+       int new_fps = 0;
+       int attribute_index = 0;
+
+       camera_fps_list_s *fps_list = NULL;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+       camera_device_capability_resolution_s *_resolution = NULL;
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+
+       _resolution = hcamcorder->mmcam_capability->current_resolution;
+
+       mmf_return_val_if_fail(_resolution, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+       ret = mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_CAMERA_FPS, &fps,
+               NULL);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("get current preview fps failed[0x%x]", ret);
+               return ret;
+       }
+
+       fps_list = &_resolution->fps_list;
+
+       for (fps_index = 0 ; fps_index < fps_list->count ; fps_index++) {
+               if (fps == fps_list->fps[fps_index]) {
+                       MMCAM_LOG_INFO("current fps[%d] is supported", fps);
+                       return MM_ERROR_NONE;
+               }
+       }
+
+       new_fps = fps_list->fps[_resolution->default_fps_index];
+
+       MMCAM_LOG_INFO("set new default fps[%d], old fps[%d)", new_fps, fps);
+
+       ret = mm_attrs_get_index(MMF_CAMCORDER_ATTRS(handle), MMCAM_CAMERA_FPS, &attribute_index);
+       ret |= mm_attrs_set_int(MMF_CAMCORDER_ATTRS(handle), attribute_index, new_fps);
+       ret |= mm_attrs_commit(MMF_CAMCORDER_ATTRS(handle), attribute_index);
+
+       MMCAM_LOG_INFO("done [0x%x]", ret);
+
+       return ret;
+}
+
+
+int _mmcamcorder_capability_get_preview_fps_list_by_resolution(MMHandleType handle,
+       int width, int height, int **fps_list, int *count, int *default_fps)
+{
+       int i = 0;
+
+       camera_device_capability_format_s *_format = NULL;
+       camera_device_capability_resolution_s *_resolution = NULL;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+       mmf_return_val_if_fail(hcamcorder->mmcam_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+       mmf_return_val_if_fail(fps_list && count && default_fps, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
+
+       _format = hcamcorder->mmcam_capability->current_format;
+       mmf_return_val_if_fail(_format, MM_ERROR_CAMCORDER_INTERNAL);
+
+       for (i = 0 ; i < _format->resolution_count ; i++) {
+               _resolution = _format->resolution[i];
+               if (!_resolution) {
+                       MMCAM_LOG_WARNING("NULL capability resolution[%d]", i);
+                       continue;
+               }
+
+               if (width == _resolution->width && height == _resolution->height) {
+                       *fps_list = _resolution->fps_list.fps;
+                       *count = _resolution->fps_list.count;
+                       *default_fps = _resolution->fps_list.fps[_resolution->default_fps_index];
+
+                       MMCAM_LOG_INFO("matched resolution[%dx%d] -> fps count[%d],default[%d]",
+                               width, height, *count, *default_fps);
+
+                       return MM_ERROR_NONE;
+               }
+       }
+
+       MMCAM_LOG_ERROR("should not be reached here for [%dx%d]", width, height);
+
+       return MM_ERROR_CAMCORDER_INTERNAL;
+}
index 12d0699864e6a0e625146b1d7641504529a5d278..9a43875b51fd609e952733c446babef9377dfbf7 100644 (file)
 /*-----------------------------------------------------------------------
 |    LOCAL VARIABLE DEFINITIONS                                                |
 -----------------------------------------------------------------------*/
-#define DEFAULT_AUDIO_BUFFER_INTERVAL   50
-#define DEFAULT_ENCODED_PREVIEW_BITRATE (1024*1024*4)
+#define DEFAULT_AUDIO_BUFFER_INTERVAL       50
+#define DEFAULT_ENCODED_PREVIEW_BITRATE     (1024*1024*4)
 
-#define MMCAMCORDER_CONF_FILEPATH_LENGTH 128
-#define MMCAMCORDER_BUFFER_LINE_MAX      256
+#define MMCAMCORDER_CONF_FILEPATH_LENGTH    128
+#define MMCAMCORDER_BUFFER_LINE_MAX         256
+
+#define BUFFER_NUM_DETAILS                  256
+#define BUFFER_NUM_TOKEN                    64
 
 char *get_new_string(char* src_string)
 {
@@ -1001,8 +1004,6 @@ int _mmcamcorder_conf_get_info(MMHandleType handle, int type, const char *ConfFi
 
 int _mmcamcorder_conf_parse_info(MMHandleType handle, int type, FILE *fp, camera_conf **configure_info)
 {
-       const unsigned int BUFFER_NUM_DETAILS = 256;
-       const unsigned int BUFFER_NUM_TOKEN = 20;
        size_t buffer_line_size = MMCAMCORDER_BUFFER_LINE_MAX;
        const char* delimiters = " |=,\t\r\n";
 
@@ -1016,8 +1017,8 @@ int _mmcamcorder_conf_parse_info(MMHandleType handle, int type, FILE *fp, camera
        int read_main = 0;
 
        char *buffer_string = NULL;
-       char *buffer_details[BUFFER_NUM_DETAILS];
-       char *buffer_token[BUFFER_NUM_TOKEN];
+       char *buffer_details[BUFFER_NUM_DETAILS] = {NULL, };
+       char *buffer_token[BUFFER_NUM_TOKEN] = {NULL, };
        char *token = NULL;
        char *category_name = NULL;
        char *detail_string = NULL;
@@ -1229,8 +1230,10 @@ void _mmcamcorder_conf_release_info(MMHandleType handle, camera_conf **configure
        for (i = 0 ; i < category_num ; i++) {
                if (temp_conf->info[i]) {
                        for (j = 0 ; j < temp_conf->info[i]->count ; j++) {
-                               if (temp_conf->info[i]->detail_info[j] == NULL)
+                               if (temp_conf->info[i]->detail_info[j] == NULL) {
+                                       MMCAM_LOG_WARNING("[%d][%d][%d] -> NULL", temp_conf->type, i, j);
                                        continue;
+                               }
 
                                if (_mmcamcorder_conf_get_value_type(handle, temp_conf->type, i, ((type_element*)(temp_conf->info[i]->detail_info[j]))->name, &type)) {
                                        switch (type) {
@@ -1364,14 +1367,12 @@ int _mmcamcorder_conf_get_value_type(MMHandleType handle, int type, int category
 
 int _mmcamcorder_conf_add_info(MMHandleType handle, int type, conf_detail **info, char **buffer_details, int category, int count_details)
 {
-       const int BUFFER_NUM_TOKEN = 256;
-
        int i = 0;
        int j = 0;
        int count_token;
        int value_type;
        char *token = NULL;
-       char *buffer_token[BUFFER_NUM_TOKEN];
+       char *buffer_token[BUFFER_NUM_TOKEN] = {NULL, };
        char *user_ptr = NULL;
 
        const char *delimiters     = " |=,\t\r\n";
@@ -1385,6 +1386,11 @@ int _mmcamcorder_conf_add_info(MMHandleType handle, int type, conf_detail **info
        (*info)->count = count_details;
 
        for (i = 0 ; i < count_details ; i++) {
+               if (!buffer_details[i]) {
+                       MMCAM_LOG_WARNING("t[%d],cat[%d],index[%d]- NULL > skip", type, category, i);
+                       continue;
+               }
+
                MMCAM_LOG_VERBOSE("Read line \"%s\"", buffer_details[i]);
                count_token = 0;
                token = strtok_r(buffer_details[i], delimiters, &user_ptr);
index 2f9115c9cde8d0a287691203b143d3351d0cb3ae..dbf4b13175ad44f46f9fee3991db0e127ea6e37d 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <mm_error.h>
 #include "mm_camcorder_internal.h"
+#include "mm_camcorder_capability.h"
 #include <mm_types.h>
 
 #include <gst/video/colorbalance.h>
@@ -151,6 +152,9 @@ static gint __mmcamcorder_init_handle(mmf_camcorder_t **hcamcorder, int device_t
        if (device_type != MM_VIDEO_DEVICE_NONE) {
                new_handle->gdbus_info_sound = _mmcamcorder_gdbus_info_new();
                new_handle->gdbus_info_solo_sound = _mmcamcorder_gdbus_info_new();
+
+               if (_mmcamcorder_capability_init((MMHandleType)new_handle) != MM_ERROR_NONE)
+                       MMCAM_LOG_WARNING("failed to init capability");
        }
 
        /* create task thread */
@@ -258,6 +262,11 @@ static void __mmcamcorder_deinit_handle(mmf_camcorder_t *hcamcorder)
        g_mutex_clear(&hcamcorder->task_thread_lock);
        g_cond_clear(&hcamcorder->task_thread_cond);
 
+       if (hcamcorder->mmcam_capability) {
+               if (_mmcamcorder_capability_deinit((MMHandleType)hcamcorder) != MM_ERROR_NONE)
+                       MMCAM_LOG_WARNING("failed to deinit capability");
+       }
+
        if (hcamcorder->model_name)
                free(hcamcorder->model_name);
 
@@ -715,6 +724,9 @@ int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info)
                if (ret != MM_ERROR_NONE)
                        goto _ERR_DEFAULT_VALUE_INIT;
 
+               if (_mmcamcorder_capability_update_preview_format_list((MMHandleType)hcamcorder) != MM_ERROR_NONE)
+                       MMCAM_LOG_WARNING("update preview format list failed");
+
                /* add DPM camera policy changed callback */
                if (hcamcorder->dpm_handle) {
                        ret = dpm_add_policy_changed_cb(hcamcorder->dpm_handle, "camera",
index 5f220e2ce45e42ef8f34b0fa68fac49cc783ecd9..5d55c1ad5e5d11a0f683ec1e957cee4a7a0c9eac 100644 (file)
@@ -27,6 +27,7 @@
 #include "mm_camcorder_internal.h"
 #include "mm_camcorder_platform.h"
 #include "mm_camcorder_configure.h"
+#include "mm_camcorder_capability.h"
 
 /*---------------------------------------------------------------------------
 |    GLOBAL VARIABLE DEFINITIONS for internal                                                          |
@@ -754,40 +755,24 @@ int _mmcamcorder_convert_msl_to_sensor(MMHandleType handle, int attr_idx, int ms
 
 int _mmcamcorder_get_fps_array_by_resolution(MMHandleType handle, int width, int height,  MMCamAttrsInfo* fps_info)
 {
-       MMCamAttrsInfo *infoW = NULL;
-       MMCamAttrsInfo *infoH = NULL;
        int i = 0;
-       char nameFps[16] = {0,};
+       char nameFps[16] = {0, };
        bool valid_check = false;
 
-       type_int_array *fps_array;
+       MMCamAttrsInfo infoW;
+       MMCamAttrsInfo infoH;
+       type_int_array *fps_array = NULL;
 
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
 
        MMCAM_LOG_DEBUG("resolution %dx%d", width, height);
 
-       infoW = (MMCamAttrsInfo*)calloc(1, sizeof(MMCamAttrsInfo));
-       if (infoW == NULL) {
-               MMCAM_LOG_ERROR("failed to alloc infoW");
-               return MM_ERROR_CAMCORDER_LOW_MEMORY;
-       }
-
-       infoH = (MMCamAttrsInfo*)calloc(1, sizeof(MMCamAttrsInfo));
-       if (infoH == NULL) {
-               MMCAM_LOG_ERROR("failed to alloc infoH");
-
-               free(infoW);
-               infoW = NULL;
-
-               return MM_ERROR_CAMCORDER_LOW_MEMORY;
-       }
+       mm_camcorder_get_attribute_info(handle, MMCAM_CAMERA_WIDTH, &infoW);
+       mm_camcorder_get_attribute_info(handle, MMCAM_CAMERA_HEIGHT, &infoH);
 
-       mm_camcorder_get_attribute_info(handle, MMCAM_CAMERA_WIDTH, infoW);
-       mm_camcorder_get_attribute_info(handle, MMCAM_CAMERA_HEIGHT, infoH);
-
-       for (i = 0; i < infoW->int_array.count; i++) {
-               MMCAM_LOG_VERBOSE("check resolution %dx%d", infoW->int_array.array[i], infoH->int_array.array[i]);
-               if (infoW->int_array.array[i] == width && infoH->int_array.array[i] == height) {
+       for (i = 0; i < infoW.int_array.count; i++) {
+               MMCAM_LOG_VERBOSE("check resolution %dx%d", infoW.int_array.array[i], infoH.int_array.array[i]);
+               if (infoW.int_array.array[i] == width && infoH.int_array.array[i] == height) {
                        valid_check = true;
                        snprintf(nameFps, sizeof(nameFps), "FPS%d", i);
                        MMCAM_LOG_INFO("nameFps[%s]", nameFps);
@@ -795,16 +780,17 @@ int _mmcamcorder_get_fps_array_by_resolution(MMHandleType handle, int width, int
                }
        }
 
-       free(infoW);
-       infoW = NULL;
-       free(infoH);
-       infoH = NULL;
-
        if (!valid_check) {
                MMCAM_LOG_ERROR("FAILED : Can't find the valid resolution from attribute.");
                return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
        }
 
+       /* get fps list from capability first. */
+       if (_mmcamcorder_capability_get_preview_fps_list_by_resolution(handle, width, height,
+               &fps_info->int_array.array, &fps_info->int_array.count, &fps_info->int_array.def) == MM_ERROR_NONE)
+               return MM_ERROR_NONE;
+
+       /* get fps list from ini if it's failed from capability. */
        if (!_mmcamcorder_conf_get_value_int_array(hcamcorder->conf_ctrl, CONFIGURE_CATEGORY_CTRL_CAMERA, nameFps, &fps_array)) {
                MMCAM_LOG_ERROR("FAILED : Can't find the valid FPS array.");
                return MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
@@ -953,6 +939,8 @@ int _mmcamcorder_init_attr_from_configure(MMHandleType handle, MMCamConvertingCa
                }
        }
 
+       hcamcorder->is_configured = TRUE;
+
        MMCAM_LOG_INFO("done");
 
        return ret;