From: Inki Dae Date: Fri, 29 Nov 2024 02:02:40 +0000 (+0900) Subject: backends/camera_api: set preview resolution with given fps X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aa1f06613f3e2676136be5966f415caa0ed291b8;p=platform%2Fcore%2Fapi%2Fsingleo.git backends/camera_api: set preview resolution with given fps Set preview resoultion with given fps. Preview resolution has supported fps so find a proper resolution which supports the user-given fps and set it. In addition, this patch adds YUYV pixel format support. Change-Id: Ie45053c099441463061976fbf6faf1830ee676d9 Signed-off-by: Inki Dae --- diff --git a/input/backends/camera_api/include/CameraApiBackend.h b/input/backends/camera_api/include/CameraApiBackend.h index 5e73758..5fc6d89 100644 --- a/input/backends/camera_api/include/CameraApiBackend.h +++ b/input/backends/camera_api/include/CameraApiBackend.h @@ -42,8 +42,10 @@ private: bool _isCaptured { false }; IInputObserver *_observer {}; cv::Mat _cvCaptureImage; - camera_pixel_format_e _defaultPreviewPixelFormat { CAMERA_PIXEL_FORMAT_I420 }; - camera_pixel_format_e _defaultCapturePixelFormat { CAMERA_PIXEL_FORMAT_I420 }; + std::vector _defaultPreviewPixelFormats = { CAMERA_PIXEL_FORMAT_YUYV, + CAMERA_PIXEL_FORMAT_I420 }; + std::vector _defaultCapturePixelFormats = { CAMERA_PIXEL_FORMAT_I420, + CAMERA_PIXEL_FORMAT_YUYV }; std::vector _validPreviewPixelFormat; std::vector _validCapturePixelFormat; std::vector _validPreviewResolution; @@ -88,6 +90,7 @@ private: static void captureCompletedCb(void *user_data); static bool previewFpsCb(camera_attr_fps_e fps, void *user_data); static bool compareSizesDescending(const cv::Size &a, const cv::Size &b); + void setPreviewResolutionAndFps(unsigned int fps); std::mutex &getMutex() { return _capture_mutex; diff --git a/input/backends/camera_api/src/CameraApiBackend.cpp b/input/backends/camera_api/src/CameraApiBackend.cpp index 69c354b..aa38e74 100644 --- a/input/backends/camera_api/src/CameraApiBackend.cpp +++ b/input/backends/camera_api/src/CameraApiBackend.cpp @@ -90,17 +90,24 @@ void CameraApiBackend::previewCb(camera_preview_data_s *data, void *user_data) if (!context->_observer) return; - if (data->num_of_planes != 3 || data->format != CAMERA_PIXEL_FORMAT_I420) { + if (data->format != CAMERA_PIXEL_FORMAT_I420 && data->format != CAMERA_PIXEL_FORMAT_YUYV) { SINGLEO_LOGE("Number of planes or pixel format not supported."); throw InvalidParameter("Number of planes or pixel format not supported."); } // TODO. consider for other plane type and pixel format support later. - cv::Mat cv_src(data->height + data->height / 2, data->width, CV_8UC1, data->data.triple_plane.y); - cv::Mat cv_dst; + SINGLEO_LOGD("width = %d, height = %d, number of planes = %d", data->width, data->height, data->num_of_planes); - cv::cvtColor(cv_src, cv_dst, cv::COLOR_YUV2BGR_I420); + cv::Mat cv_dst {}; + + if (data->format == CAMERA_PIXEL_FORMAT_YUYV) { + cv::Mat cv_src(data->height, data->width, CV_8UC2, data->data.single_plane.yuv); + cv::cvtColor(cv_src, cv_dst, cv::COLOR_YUV2BGR_YUYV); + } else { + cv::Mat cv_src(data->height + data->height / 2, data->width, CV_8UC1, data->data.triple_plane.y); + cv::cvtColor(cv_src, cv_dst, cv::COLOR_YUV2BGR_I420); + } ImageDataType data_type; @@ -175,11 +182,62 @@ bool CameraApiBackend::previewFpsCb(camera_attr_fps_e fps, void *user_data) return true; } +void CameraApiBackend::setPreviewResolutionAndFps(unsigned int fps) +{ + camera_attr_fps_e givenFps = CAMERA_ATTR_FPS_AUTO; + + try { + givenFps = _fpsTypeTable.at(fps); + } catch (const std::out_of_range &e) { + SINGLEO_LOGE("CameraApiBackend: a given fps(%d) is out_of_range.", fps); + throw InvalidOperation("CameraApiBackend: a given fps is out_of_range."); + } + + auto fps_it = find(_validFps.begin(), _validFps.end(), givenFps); + if (fps_it == _validFps.end()) { + SINGLEO_LOGE("CameraApiBackend: fps(%d) is not supported.", fps); + throw InvalidOperation("CameraApiBackend: fps is not supported."); + } + + bool isFpsSupported = false; + cv::Size validResolution {}; + + for (auto &resolution : _validPreviewResolution) { + int ret = camera_set_preview_resolution(_camera, resolution.width, resolution.height); + if (ret != CAMERA_ERROR_NONE) { + SINGLEO_LOGE("CameraApiBackend: camera_set_preview_resolution failed. ret: %d", ret); + throw InvalidOperation("CameraApiBackend: camera_set_preview_resolution failed."); + } + + ret = camera_attr_set_preview_fps(_camera, givenFps); + if (ret == CAMERA_ERROR_NONE) { + isFpsSupported = true; + validResolution = resolution; + break; + } + + SINGLEO_LOGW("CameraApiBackend: (%d)fps not supported with %dx%d so retry.", fps, resolution.width, + resolution.height); + } + + if (!isFpsSupported) + throw InvalidOperation("CameraApiBackend: fps(%d) is not supported.", fps); + + SINGLEO_LOGD("CameraApiBackend: preview resolution(width: %d, height: %d) has been set with fps(%d)", + validResolution.width, validResolution.height, fps); +} + void CameraApiBackend::configure(const CameraConfig &config) { setActiveCameraDevice(config.device_id); - int ret = camera_foreach_supported_preview_resolution(_camera, previewResolutionCb, this); + int ret = camera_attr_foreach_supported_fps(_camera, previewFpsCb, this); + if (ret != CAMERA_ERROR_NONE) { + SINGLEO_LOGE("CameraApiBackend: camera_attr_foreach_supported_fps failed. ret: %d", ret); + throw InvalidOperation("CameraApiBackend: camera_attr_foreach_supported_fps failed."); + } + + ret = camera_foreach_supported_preview_resolution(_camera, previewResolutionCb, this); if (ret != CAMERA_ERROR_NONE) { SINGLEO_LOGE("CameraApiBackend: camera_foreach_supported_preview_resolution failed. ret: %d", ret); throw InvalidOperation("CameraApiBackend: camera_foreach_supported_preview_resolution failed."); @@ -195,14 +253,7 @@ void CameraApiBackend::configure(const CameraConfig &config) _validPreviewResolution[0].width, _validPreviewResolution[0].height); // TODO. set user-given resolution with the option string of singleo API later. - ret = camera_set_preview_resolution(_camera, _validPreviewResolution[0].width, _validPreviewResolution[0].height); - if (ret != CAMERA_ERROR_NONE) { - SINGLEO_LOGE("CameraApiBackend: camera_set_preview_resolution failed. ret: %d", ret); - throw InvalidOperation("CameraApiBackend: camera_set_preview_resolution failed."); - } - - SINGLEO_LOGD("Set camera resolution for capture with width(%d) and height(%d) in default.", - _validCaptureResolution[0].width, _validCaptureResolution[0].height); + setPreviewResolutionAndFps(config.fps); ret = camera_set_capture_resolution(_camera, _validCaptureResolution[0].width, _validCaptureResolution[0].height); if (ret != CAMERA_ERROR_NONE) { @@ -217,14 +268,24 @@ void CameraApiBackend::configure(const CameraConfig &config) } // TODO. read default pixel format from json configuration file later. - auto preview_it = - find(_validPreviewPixelFormat.begin(), _validPreviewPixelFormat.end(), _defaultPreviewPixelFormat); - if (preview_it == _validPreviewPixelFormat.end()) { + + // Select preview format from the list of supported formats. + camera_pixel_format_e previewPixelFormat { CAMERA_PIXEL_FORMAT_INVALID }; + + for (auto format : _defaultPreviewPixelFormats) { + auto preview_it = find(_validPreviewPixelFormat.begin(), _validPreviewPixelFormat.end(), format); + if (preview_it != _validPreviewPixelFormat.end()) { + previewPixelFormat = format; + break; + } + } + + if (previewPixelFormat == CAMERA_PIXEL_FORMAT_INVALID) { SINGLEO_LOGE("Invalid preview pixel format type."); throw InvalidOperation("CameraApiBackend: Invalid preview pixel format type."); } - ret = camera_set_preview_format(_camera, _defaultPreviewPixelFormat); + ret = camera_set_preview_format(_camera, previewPixelFormat); if (ret != CAMERA_ERROR_NONE) { SINGLEO_LOGE("CameraApiBackend: camera_set_preview_format failed. ret: %d", ret); throw InvalidOperation("CameraApiBackend: camera_set_preview_format failed."); @@ -237,55 +298,28 @@ void CameraApiBackend::configure(const CameraConfig &config) } // TODO. read default pixel format from json configuration file later. - auto capture_it = - find(_validCapturePixelFormat.begin(), _validCapturePixelFormat.end(), _defaultCapturePixelFormat); - if (capture_it == _validCapturePixelFormat.end()) { - SINGLEO_LOGE("Invalid capture pixel format type."); - throw InvalidOperation("CameraApiBackend: Invalid capture pixel format type."); - } - - ret = camera_set_capture_format(_camera, _defaultCapturePixelFormat); - if (ret != CAMERA_ERROR_NONE) { - SINGLEO_LOGE("CameraApiBackend: camera_set_capture_format failed. ret: %d", ret); - throw InvalidOperation("CameraApiBackend: camera_set_capture_format failed."); - } - ret = camera_attr_foreach_supported_fps(_camera, previewFpsCb, this); - if (ret != CAMERA_ERROR_NONE) { - SINGLEO_LOGE("CameraApiBackend: camera_attr_foreach_supported_fps failed. ret: %d", ret); - throw InvalidOperation("CameraApiBackend: camera_attr_foreach_supported_fps failed."); - } - - camera_attr_fps_e givenFps = CAMERA_ATTR_FPS_AUTO; + // Select capture format from the list of supported formats. + camera_pixel_format_e capturePixelFormat { CAMERA_PIXEL_FORMAT_INVALID }; - try { - givenFps = _fpsTypeTable.at(config.fps); - } catch (const std::out_of_range &e) { - SINGLEO_LOGE("CameraApiBackend: a given fps(%d) is out_of_range.", config.fps); - throw InvalidOperation("CameraApiBackend: a given fps is out_of_range."); - } - - auto fps_it = find(_validFps.begin(), _validFps.end(), givenFps); - if (fps_it == _validFps.end()) { - SINGLEO_LOGE("CameraApiBackend: fps(%d) is not supported.", config.fps); - throw InvalidOperation("CameraApiBackend: fps is not supported."); + for (auto format : _defaultCapturePixelFormats) { + auto preview_it = find(_validCapturePixelFormat.begin(), _validCapturePixelFormat.end(), format); + if (preview_it != _validCapturePixelFormat.end()) { + capturePixelFormat = format; + break; + } } - ret = camera_attr_set_preview_fps(_camera, givenFps); - if (ret != CAMERA_ERROR_NONE) { - SINGLEO_LOGE("CameraApiBackend: camera_attr_set_preview_fps failed. ret: %d", ret); - throw InvalidOperation("CameraApiBackend: camera_attr_set_preview_fps failed."); + if (capturePixelFormat == CAMERA_PIXEL_FORMAT_INVALID) { + SINGLEO_LOGE("Invalid capture pixel format type."); + throw InvalidOperation("CameraApiBackend: Invalid capture pixel format type."); } - camera_attr_fps_e previewFps; - - ret = camera_attr_get_preview_fps(_camera, &previewFps); + ret = camera_set_capture_format(_camera, capturePixelFormat); if (ret != CAMERA_ERROR_NONE) { - SINGLEO_LOGE("CameraApiBackend: camera_attr_get_preview_fps failed. ret: %d", ret); - throw InvalidOperation("CameraApiBackend: camera_attr_get_preview_fps failed."); + SINGLEO_LOGE("CameraApiBackend: camera_set_capture_format failed. ret: %d", ret); + throw InvalidOperation("CameraApiBackend: camera_set_capture_format failed."); } - - SINGLEO_LOGD("CameraApiBackend: previewFps: %d", previewFps); } void CameraApiBackend::captureCb(camera_image_data_s *image, camera_image_data_s *postview,