Update supported FPS when resolution is changed 42/320042/6 accepted/tizen/unified/20241112.160412 accepted/tizen/unified/x/20241218.032727 accepted/tizen/unified/x/asan/20241224.004453
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 7 Nov 2024 05:14:43 +0000 (14:14 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 11 Nov 2024 11:30:24 +0000 (20:30 +0900)
- Previously, unsupported FPS could be used after resolution is changed.
- The FPS list can be different by resolution,
  then it should be checked and updated if needed.

[Version] 1.3.2
[Issue Type] Improvement

Change-Id: I5774006e5e24810976261f58e4562497cdd19eca
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/libmm-camcorder.spec
src/include/mm_camcorder_configure.h
src/include/mm_camcorder_internal.h
src/include/mm_camcorder_util.h
src/mm_camcorder_attribute.c
src/mm_camcorder_capability.c
src/mm_camcorder_configure.c
src/mm_camcorder_platform.c
src/mm_camcorder_util.c

index bd8aada39e7377c701382cbaf63a4c915705e4e8..590112cb99940f513501dda0af17d74c00d5dbb9 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       libmm-camcorder
 Summary:    Camera and recorder library
-Version:    1.3.1
+Version:    1.3.2
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 278b2bf1347e0af330aa0e44566bd069368f7d8a..f9619a4843946e9da3674d7fe9e85267c459ecbd 100644 (file)
@@ -400,6 +400,7 @@ int _mmcamcorder_conf_get_default_element(MMHandleType handle, int type, int cat
 int _mmcamcorder_conf_get_category_size(MMHandleType handle, int type, int category, int *size);
 void _mmcamcorder_conf_get_element_and_name(MMHandleType handle, camera_conf *configure_info, int category,
        const char *name, type_element **element, const char **element_name);
+int _mmcamcorder_conf_update_preview_fps(MMHandleType handle, int width, int height);
 
 #ifdef __cplusplus
 }
index b2ce52c8e18d1abd4f0bae0c2a6d71e735fe22f7..c3c130ad2b2d8a2dd61cc01f19afe748595b50c5 100644 (file)
@@ -94,6 +94,12 @@ extern "C" {
                return (val); \
        }
 
+#define mmf_return_val_if_fail_warning(expr, val) \
+       if (!(expr)) { \
+               MMCAM_LOG_WARNING("failed [%s]", #expr); \
+               return (val); \
+       }
+
 
 #ifndef ARRAY_SIZE
 /**
index 7e7eb49b344abd49e9f8d06a87bc83a34bfa1c7f..bc4e6de387dbab317e21f8ace230b88e482e6217 100644 (file)
@@ -319,6 +319,9 @@ gboolean _mmcamcorder_resize_frame(unsigned char *src_data, unsigned int src_wid
 gboolean _mmcamcorder_downscale_UYVYorYUYV(unsigned char *src, unsigned int src_width, unsigned int src_height,
        unsigned char **dst, unsigned int dst_width, unsigned int dst_height);
 
+/* Camera preview */
+int _mmcamcorder_set_fps_on_preview_resolution_update(MMHandleType handle, int new_fps);
+
 /* Recording */
 /* find top level tag only, do not use this function for finding sub level tags.
    tag_fourcc is Four-character-code (FOURCC) */
index 6a346f712110972689975812d869c1e23b90d120..49866cbebc064d604a888201d1da0195390dcad9 100644 (file)
@@ -2392,8 +2392,8 @@ bool _mmcamcorder_commit_camera_fps(MMHandleType handle, int attr_idx, const MMA
 {
        mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
        MMCamAttrsInfo fps_info;
-       int resolution_width = 0;
-       int resolution_height = 0;
+       int width = 0;
+       int height = 0;
        int i = 0;
        int ret = 0;
        int current_state = MM_CAMCORDER_STATE_NONE;
@@ -2418,8 +2418,8 @@ bool _mmcamcorder_commit_camera_fps(MMHandleType handle, int attr_idx, const MMA
        }
 
        ret = mm_camcorder_get_attributes(handle, NULL,
-               MMCAM_CAMERA_WIDTH, &resolution_width,
-               MMCAM_CAMERA_HEIGHT, &resolution_height,
+               MMCAM_CAMERA_WIDTH, &width,
+               MMCAM_CAMERA_HEIGHT, &height,
                NULL);
 
        if (ret != MM_ERROR_NONE) {
@@ -2427,9 +2427,9 @@ bool _mmcamcorder_commit_camera_fps(MMHandleType handle, int attr_idx, const MMA
                return FALSE;
        }
 
-       ret = mm_camcorder_get_fps_list_by_resolution(handle, resolution_width, resolution_height, &fps_info);
+       ret = mm_camcorder_get_fps_list_by_resolution(handle, width, height, &fps_info);
        if (ret != MM_ERROR_NONE) {
-               MMCAM_LOG_ERROR("FAILED : coult not get FPS values by resolution.");
+               MMCAM_LOG_ERROR("FAILED : FPS list by resolution[%dx%d]", width, height);
                return FALSE;
        }
 
@@ -2624,22 +2624,28 @@ bool _mmcamcorder_commit_camera_height(MMHandleType handle, int attr_idx, const
        sc->info_video->preview_width = width;
        sc->info_video->preview_height = height;
 
-       /* 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;
-               }
+       /* update FPS */
+       do {
+               if (!hcamcorder->is_configured)
+                       break;
 
-               hcamcorder->on_preview_resolution_update = TRUE;
-               mm_ret = _mmcamcorder_capability_update_preview_fps(hcamcorder);
-               hcamcorder->on_preview_resolution_update = FALSE;
+               if (hcamcorder->mmcam_capability) {
+                       /* from capability */
+                       mm_ret = _mmcamcorder_capability_update_capability_resolution(handle, width, height);
+                       if (mm_ret != MM_ERROR_NONE)
+                               break;
 
-               if (mm_ret != MM_ERROR_NONE) {
-                       MMCAM_LOG_ERROR("update resolution list failed[0x%x]", mm_ret);
-                       return false;
+                       mm_ret = _mmcamcorder_capability_update_preview_fps(hcamcorder);
+               } else {
+                       /* from ini */
+                       mm_ret = _mmcamcorder_conf_update_preview_fps(handle, width, height);
                }
+       } while (0);
+
+       if (mm_ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("[configured:%d,capability:%p] update resolution/FPS failed[0x%x]",
+                       hcamcorder->is_configured, hcamcorder->mmcam_capability, mm_ret);
+               return false;
        }
 
        if (current_state != MM_CAMCORDER_STATE_PREPARE) {
index cb1cfb425135bb35e42b54ad40179f6a2db28914..265999c24ddddea08189ec42b81a56337901773e 100644 (file)
@@ -110,7 +110,7 @@ static int __mmcamcorder_capability_update_attribute_int_array(MMHandleType attr
 
 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);
+       mmf_return_val_if_fail_warning(mmcam_capability, NULL);
 
        if (device_index >= mmcam_capability->list.device_count) {
                MMCAM_LOG_ERROR("invalid device index[%d] vs device count[%d]",
@@ -375,7 +375,7 @@ int _mmcamcorder_capability_update_preview_format_list(MMHandleType handle)
 
        _capability = __mmcamcorder_capability_get_capability(hcamcorder->mmcam_capability, hcamcorder->device_type);
 
-       mmf_return_val_if_fail(_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
+       mmf_return_val_if_fail_warning(_capability, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
 
        MMCAM_LOG_INFO("device[%d], capability format count[%d]",
                hcamcorder->device_type, _capability->format_count);
@@ -562,8 +562,6 @@ 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;
 
@@ -594,17 +592,12 @@ int _mmcamcorder_capability_update_preview_fps(MMHandleType handle)
                }
        }
 
-       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("update fps [%d] -> [%d] for resolution[%ux%u]",
+               fps, fps_list->fps[_resolution->default_fps_index],
+               _resolution->width, _resolution->height);
 
-       MMCAM_LOG_INFO("done [0x%x]", ret);
-
-       return ret;
+       return _mmcamcorder_set_fps_on_preview_resolution_update(handle,
+               fps_list->fps[_resolution->default_fps_index]);
 }
 
 
@@ -619,7 +612,7 @@ int _mmcamcorder_capability_get_preview_fps_list_by_resolution(MMHandleType hand
        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_warning(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;
index b946112b98d2a94f487f9d6aec4cfc1f2f5a1b57..82a11b2704449f470063a02240d29c711bf92c81 100644 (file)
@@ -2730,3 +2730,40 @@ int _mmcamcorder_get_available_format(MMHandleType handle, int conf_category, in
 
        return total_count;
 }
+
+int _mmcamcorder_conf_update_preview_fps(MMHandleType handle, int width, int height)
+{
+       int i = 0;
+       int fps = 0;
+       int ret = MM_ERROR_NONE;
+       MMCamAttrsInfo info;
+
+       ret = mm_camcorder_get_attributes(handle, NULL,
+               MMCAM_CAMERA_FPS, &fps,
+               NULL);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("get fps failed[0x%x]", ret);
+               return MM_ERROR_CAMCORDER_INTERNAL;
+       }
+
+       ret = mm_camcorder_get_fps_list_by_resolution(handle, width, height, &info);
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("get fps list for [%dx%d] failed[0x%x]", width, height, ret);
+               return MM_ERROR_CAMCORDER_INTERNAL;
+       }
+
+       for (i = 0 ; i < info.int_array.count ; i++) {
+               if (info.int_array.array[i] != fps)
+                       continue;
+
+               MMCAM_LOG_INFO("new resolution[%dx%d] supports current fps[%d]",
+                       width, height, fps);
+
+               return MM_ERROR_NONE;
+       }
+
+       MMCAM_LOG_INFO("update fps [%d] -> [%d] for resolution[%dx%d]",
+               fps, info.int_array.def, width, height);
+
+       return _mmcamcorder_set_fps_on_preview_resolution_update(handle, info.int_array.def);
+}
index c4d5058d6440b8c1f073c819162a92d38fa41b7d..97541c05dba5cdfe9dcf5d3be218db33c606ec45 100644 (file)
@@ -757,7 +757,6 @@ int _mmcamcorder_get_fps_array_by_resolution(MMHandleType handle, int width, int
 {
        int i = 0;
        char nameFps[16] = {0, };
-       bool valid_check = false;
 
        MMCamAttrsInfo infoW;
        MMCamAttrsInfo infoH;
@@ -773,15 +772,14 @@ int _mmcamcorder_get_fps_array_by_resolution(MMHandleType handle, int width, int
        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);
                        break;
                }
        }
 
-       if (!valid_check) {
-               MMCAM_LOG_ERROR("FAILED : Can't find the valid resolution from attribute.");
+       if (i >= infoW.int_array.count) {
+               MMCAM_LOG_ERROR("FAILED : resolution[%dx%d] from attribute.", width, height);
                return MM_ERROR_CAMCORDER_NOT_SUPPORTED;
        }
 
@@ -792,7 +790,7 @@ int _mmcamcorder_get_fps_array_by_resolution(MMHandleType handle, int width, int
 
        /* 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.");
+               MMCAM_LOG_ERROR("FAILED : [%s] array.", nameFps);
                return MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
        }
 
index 788bf0fd0978fbf817a1431f42e84c34534c7a1c..4c94acc50be99b4add1df84938f712e2c97b9fe4 100644 (file)
@@ -2740,3 +2740,30 @@ void _mmcamcorder_set_property_array_int(GstElement *element, const char *proper
        g_value_unset(&tmp);
        g_value_unset(&value);
 }
+
+int _mmcamcorder_set_fps_on_preview_resolution_update(MMHandleType handle, int new_fps)
+{
+       int ret = MM_ERROR_NONE;
+       int attribute_index = 0;
+
+       mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
+
+       mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
+
+       MMCAM_LOG_INFO("set new fps[%d]", new_fps);
+
+       hcamcorder->on_preview_resolution_update = TRUE;
+
+       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);
+
+       hcamcorder->on_preview_resolution_update = FALSE;
+
+       if (ret != MM_ERROR_NONE) {
+               MMCAM_LOG_ERROR("set new fps[%d] failed[0x%x]", new_fps, ret);
+               return MM_ERROR_CAMCORDER_INTERNAL;
+       }
+
+       return MM_ERROR_NONE;
+}