From 9b51335e0987c8d8bc7156add401c976156501c6 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Tue, 16 Jul 2024 15:24:50 +0900 Subject: [PATCH] Support device capability provided by camera HAL - 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 --- configure.ac | 4 + packaging/libmm-camcorder.spec | 3 +- src/Makefile.am | 4 + src/include/mm_camcorder_capability.h | 97 +++++ src/include/mm_camcorder_internal.h | 6 + src/mm_camcorder_attribute.c | 165 ++++--- src/mm_camcorder_capability.c | 593 ++++++++++++++++++++++++++ src/mm_camcorder_configure.c | 30 +- src/mm_camcorder_internal.c | 12 + src/mm_camcorder_platform.c | 48 +-- 10 files changed, 856 insertions(+), 106 deletions(-) create mode 100644 src/include/mm_camcorder_capability.h create mode 100644 src/mm_camcorder_capability.c diff --git a/configure.ac b/configure.ac index cc398fb..9f53fb7 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/packaging/libmm-camcorder.spec b/packaging/libmm-camcorder.spec index 317028e..0d07056 100755 --- a/packaging/libmm-camcorder.spec +++ b/packaging/libmm-camcorder.spec @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index b4ff0d7..bc1bde9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..1c6fa71 --- /dev/null +++ b/src/include/mm_camcorder_capability.h @@ -0,0 +1,97 @@ +/* + * libmm-camcorder + * + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * 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 +#include + + +#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__ */ diff --git a/src/include/mm_camcorder_internal.h b/src/include/mm_camcorder_internal.h index c7706e1..cddea03 100644 --- a/src/include/mm_camcorder_internal.h +++ b/src/include/mm_camcorder_internal.h @@ -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 */ diff --git a/src/mm_camcorder_attribute.c b/src/mm_camcorder_attribute.c index 62799d7..74ba10b 100644 --- a/src/mm_camcorder_attribute.c +++ b/src/mm_camcorder_attribute.c @@ -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 index 0000000..bb44ebb --- /dev/null +++ b/src/mm_camcorder_capability.c @@ -0,0 +1,593 @@ +/* + * libmm-camcorder + * + * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jeongmo Yang + * + * 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, ¤t_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, ¤t_width, + MMCAM_CAMERA_HEIGHT, ¤t_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; +} diff --git a/src/mm_camcorder_configure.c b/src/mm_camcorder_configure.c index 12d0699..9a43875 100644 --- a/src/mm_camcorder_configure.c +++ b/src/mm_camcorder_configure.c @@ -41,11 +41,14 @@ /*----------------------------------------------------------------------- | 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); diff --git a/src/mm_camcorder_internal.c b/src/mm_camcorder_internal.c index 2f9115c..dbf4b13 100644 --- a/src/mm_camcorder_internal.c +++ b/src/mm_camcorder_internal.c @@ -33,6 +33,7 @@ #include #include "mm_camcorder_internal.h" +#include "mm_camcorder_capability.h" #include #include @@ -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", diff --git a/src/mm_camcorder_platform.c b/src/mm_camcorder_platform.c index 5f220e2..5d55c1a 100644 --- a/src/mm_camcorder_platform.c +++ b/src/mm_camcorder_platform.c @@ -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; -- 2.34.1