From: Tae-Young Chung Date: Mon, 19 Jun 2023 08:23:30 +0000 (+0900) Subject: Separate some classes from mv_depthstream_test_suite X-Git-Tag: accepted/tizen/7.0/unified/20230620.164244^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=abf09606572c20a7eb9b93d0a84b3060b6ddc9e6;p=platform%2Fcore%2Fapi%2Fmediavision.git Separate some classes from mv_depthstream_test_suite [Version] 0.23.49-2 [Issue type] update Change-Id: I2fa91ff20369609406fb4e7250ad83213f42dfe1 Signed-off-by: Tae-Young Chung --- diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index 231832fc..6b67301b 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,7 +1,7 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API Version: 0.23.49 -Release: 1 +Release: 2 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause Source0: %{name}-%{version}.tar.gz diff --git a/test/testsuites/mv3d/CameraSourceFeeder.h b/test/testsuites/mv3d/CameraSourceFeeder.h new file mode 100644 index 00000000..8099bd28 --- /dev/null +++ b/test/testsuites/mv3d/CameraSourceFeeder.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_CAMERA_SOURCE_FEEDER_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_CAMERA_SOURCE_FEEDER_H__ + +#include "IFeeder.h" +#include + +class CameraSourceFeeder : public IFeeder +{ +private: + Mv3d* _mv3d; + const camera_device_e _deviceId; + + camera_h _handle; + camera_frame_meta_s _frameMeta; + + static void _camera_preview_cb(media_packet_h pkt, void *user_data); + static bool _supported_preview_fps_cb(camera_attr_fps_e fps, void *user_data); +public: + CameraSourceFeeder(); + ~CameraSourceFeeder(); + + void start(std::shared_ptr mv3d) override; + void stop() override; +}; + +CameraSourceFeeder::CameraSourceFeeder() + : _mv3d(nullptr) + , _deviceId(CAMERA_DEVICE_CAMERA3) + , _handle(nullptr) +{ + camera_create(_deviceId, &_handle); + camera_attr_foreach_supported_fps(_handle, _supported_preview_fps_cb, this); + if (!camera_is_supported_media_packet_preview_cb(_handle)) + throw std::runtime_error("not supported media packet preview cb"); +} + +CameraSourceFeeder::~CameraSourceFeeder() +{ + stop(); + + camera_destroy(_handle); + _handle = nullptr; +}; + +void CameraSourceFeeder::start(std::shared_ptr mv3d) +{ + _mv3d = mv3d.get(); + camera_set_media_packet_preview_cb(_handle, _camera_preview_cb, this); + + mv3d->resetTime(); + camera_start_preview(_handle); +} + +void CameraSourceFeeder::stop() +{ + camera_state_e state; + camera_get_state(_handle, &state); + if (state == CAMERA_STATE_PREVIEW) + camera_stop_preview(_handle); +} + +void CameraSourceFeeder::_camera_preview_cb(media_packet_h pkt, void *user_data) +{ + CameraSourceFeeder* cameraSource = static_cast(user_data); + std::cout << "_camera_preview_cb: " << cameraSource->_mv3d->checkElapsedTime() << " ms" << std::endl; + + unsigned long timestamp; + camera_attr_get_preview_frame_timestamp(cameraSource->_handle, ×tamp); + camera_attr_get_preview_frame_meta(cameraSource->_handle, &cameraSource->_frameMeta); + cameraSource->_mv3d->run(pkt, timestamp, cameraSource->_frameMeta); + media_packet_unref(pkt); +} + +bool CameraSourceFeeder::_supported_preview_fps_cb(camera_attr_fps_e fps, void *user_data) +{ + CameraSourceFeeder* cameraSource = static_cast(user_data); + if (fps == 10) { + std::cout << "Set desired camera preview fps: " << fps << std::endl; + camera_attr_set_preview_fps(cameraSource->_handle, fps); + return false; + } + return true; +} +#endif \ No newline at end of file diff --git a/test/testsuites/mv3d/DfsUtil.h b/test/testsuites/mv3d/DfsUtil.h new file mode 100644 index 00000000..2c36feb6 --- /dev/null +++ b/test/testsuites/mv3d/DfsUtil.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_DFS_UTIL_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_DFS_UTIL_H__ + +#include + +enum { STEREO_FORMAT_NONE, STEREO_FORMAT_SIDE_BY_SIDE, STEREO_FORMAT_TOP_AND_BOTTOM }; +enum { VISION_SOURCE, CAMERA_SOURCE }; +enum { NONE, OKAY }; + +class StopWatch +{ +private: + std::chrono::steady_clock::time_point start; +public: + StopWatch() = default; + ~StopWatch() = default; + + void resetTime(); + + std::chrono::milliseconds elapsedTime(); +}; + +void StopWatch::resetTime() +{ + start = std::chrono::steady_clock::now(); +} + +std::chrono::milliseconds StopWatch::elapsedTime() +{ + return std::chrono::duration_cast(std::chrono::steady_clock::now() - start); +} +#endif diff --git a/test/testsuites/mv3d/FeederFactory.h b/test/testsuites/mv3d/FeederFactory.h new file mode 100644 index 00000000..c0169592 --- /dev/null +++ b/test/testsuites/mv3d/FeederFactory.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_FEEDER_FACTORY_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_FEEDER_FACTORY_H__ + +#include "IFeeder.h" +#include "VisionSourceFeeder.h" +#include "CameraSourceFeeder.h" + +class FeederFactory +{ +private: + FeederFactory() = delete; + FeederFactory(const FeederFactory&) = delete; +public: + static std::unique_ptr createVisionSourceFeeder(int width=640, int height=400, int fps=10, int stereoFormat=STEREO_FORMAT_TOP_AND_BOTTOM) + { + return std::make_unique(width, height, fps, stereoFormat); + } + + static std::unique_ptr createCameraSourceFeeder() + { + return std::make_unique(); + } +}; +#endif diff --git a/test/testsuites/mv3d/IFeeder.h b/test/testsuites/mv3d/IFeeder.h new file mode 100644 index 00000000..c08393cc --- /dev/null +++ b/test/testsuites/mv3d/IFeeder.h @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_IFEEDER_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_IFEEDER_H__ + +#include +#include "Mv3d.h" +#include "DfsUtil.h" + +class IFeeder +{ +public: + virtual ~IFeeder(){}; + virtual void start(std::shared_ptr mv3d) = 0; + virtual void stop() = 0; +}; +#endif diff --git a/test/testsuites/mv3d/Mv3d.h b/test/testsuites/mv3d/Mv3d.h new file mode 100644 index 00000000..2fa69867 --- /dev/null +++ b/test/testsuites/mv3d/Mv3d.h @@ -0,0 +1,224 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_MV3D_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_MV3D_H__ + +#include +#include + +#include "mv_3d.h" +#include "mv_common.h" +#include "DfsUtil.h" + +#ifdef WITH_DA_PROFILE +#include +#endif + +class Mv3d +{ +private: + bool _isAsync; + int _sourceWidth; + int _sourceHeight; + unsigned char *_rawBuffer; + + mv_3d_h _3dHandle; + mv_source_h _source; + mv_engine_config_h _engineConfig; + + int _state; + std::string _calibFilePath; + std::string _depthFilePath; + StopWatch _timer; + + static void _depth_stereo_cb(mv_source_h source, unsigned short *depth, unsigned int width, unsigned int height, + void *user_data); +public: + Mv3d(int minDisparity, int maxDisparity, bool isAsync, std::string calibFilePath, int depthWidth, int depthHeight, int stereoFormat, std::string depthFilePath); + ~Mv3d(); + + void prepare(); + void run(vision_source_buffer_s *buffer); + void run(media_packet_h pkt, unsigned long& timestamp, camera_frame_meta_s& meta); + + void stop(); + + void resetTime(); + + long long int checkElapsedTime(); +}; + +Mv3d::Mv3d(int minDisparity, int maxDisparity, bool isAsync, std::string calibFilePath, int depthWidth, int depthHeight, int stereoFormat, std::string depthFilePath) + :_isAsync(isAsync) + , _sourceWidth(depthWidth) + , _sourceHeight(depthHeight) + , _rawBuffer(nullptr) + , _3dHandle(nullptr) + , _source(nullptr) + , _engineConfig(nullptr) + , _state(NONE) + , _calibFilePath("/usr/share/dfs-qcmv/stereoCalibDA.yaml") + , _depthFilePath("/tmp/depthDump.png") +{ + // MediaVision mv_engine_config_h + mv_create_engine_config(&_engineConfig); + mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_WIDTH, depthWidth); + mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_HEIGHT, depthHeight); + mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_MIN_DISPARITY, minDisparity); + mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_MAX_DISPARITY, maxDisparity); + + if (!calibFilePath.empty()) + _calibFilePath = calibFilePath; + mv_engine_config_set_string_attribute(_engineConfig, MV_3D_DEPTH_STEREO_CONFIG_FILE_PATH, _calibFilePath.c_str()); + + if (!depthFilePath.empty()) + _depthFilePath = depthFilePath; + + // MediaVision mv_3d_h + mv_3d_create(&_3dHandle); + mv_3d_configure(_3dHandle, _engineConfig); + mv_3d_set_depth_cb(_3dHandle, _depth_stereo_cb, this); + + mv_create_source(&_source); + + switch (stereoFormat) { + case STEREO_FORMAT_SIDE_BY_SIDE: + _sourceWidth <<= 1; + break; + case STEREO_FORMAT_TOP_AND_BOTTOM: + _sourceHeight <<= 1; + break; + default: + break; + } + + _rawBuffer = new unsigned char [_sourceWidth * _sourceHeight]; +} + +Mv3d::~Mv3d() +{ + if (_engineConfig || _3dHandle || _source) + stop(); +} + + +void Mv3d::prepare() +{ + mv_3d_prepare(_3dHandle); + _state = OKAY; +} + +void Mv3d::run(vision_source_buffer_s *buffer) +{ + if (_state != OKAY) + return; + + for (unsigned int h = 0; h < buffer->resolution.height; h++) { + memcpy(_rawBuffer + buffer->resolution.width * h, buffer->planes[0].data + (buffer->planes[0].align_width * h), + buffer->resolution.width); + } + + mv_source_fill_by_buffer(_source, _rawBuffer, _sourceWidth * _sourceHeight, + _sourceWidth, _sourceHeight, MEDIA_VISION_COLORSPACE_Y800); + +#ifdef WITH_DA_PROFILE + mv_source_set_timestamp(_source, static_cast(buffer->priv)); +#endif + +if (_isAsync) + mv_3d_run_async(_3dHandle, _source, nullptr, nullptr); +else + mv_3d_run(_3dHandle, _source, nullptr, nullptr); + + mv_source_clear(_source); +} + +void Mv3d::run(media_packet_h pkt, unsigned long& timestamp, camera_frame_meta_s& meta) +{ + mv_source_fill_by_media_packet(_source, pkt); + +#ifdef WITH_DA_PROFILE + da_timestamp_s daTimestamp = {timestamp, + meta.ts_soe, + meta.ts_eoe, + meta.ts_sof, + meta.ts_eof, + meta.ts_hal, + meta.ts_qmf, + meta.td_exp, + meta.ts_aux, + meta.td_aux, + meta.seqnum, + meta.flags }; + + mv_source_set_timestamp(_source, &daTimestamp); +#endif + mv_3d_run_async(_3dHandle, _source, nullptr, nullptr); + + mv_source_clear(_source); +} + +void Mv3d::stop() +{ + _state = NONE; + delete [] _rawBuffer; + + if (_source) { + mv_destroy_source(_source); + _source = nullptr; + } + + if (_3dHandle) { + mv_3d_destroy(_3dHandle); + _3dHandle = nullptr; + } + + if (_engineConfig) { + mv_destroy_engine_config(_engineConfig); + _engineConfig = nullptr; + } +} + +void Mv3d::resetTime() +{ + _timer.resetTime(); +} + +long long int Mv3d::checkElapsedTime() +{ + return static_cast(_timer.elapsedTime().count()); +} + + +void Mv3d::_depth_stereo_cb(mv_source_h source, unsigned short *depth, unsigned int width, unsigned int height, + void *user_data) +{ +#ifdef WITH_DA_PROFILE + std::cout << "_depth_stereo_cb: " << std::endl; + da_timestamp_s timestamp; + mv_source_get_timestamp(source, ×tamp); + std::cout << "timestamp [" << timestamp.timestamp << "], "; + std::cout << "ts_sof [" << timestamp.ts_sof << "], "; + std::cout << "ts_aux [" << timestamp.ts_aux << "], "; + std::cout << "ts_eof [" << timestamp.ts_eof << "], " << std::endl; +#endif + cv::Mat dump(cv::Size(width, height), CV_16U, depth); + dump.setTo(0, dump==65535); + + Mv3d* mv3d = static_cast(user_data); + cv::imwrite(mv3d->_depthFilePath, dump); +} +#endif \ No newline at end of file diff --git a/test/testsuites/mv3d/VisionSourceFeeder.h b/test/testsuites/mv3d/VisionSourceFeeder.h new file mode 100644 index 00000000..dc0bc132 --- /dev/null +++ b/test/testsuites/mv3d/VisionSourceFeeder.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MV_DEPTHSTREAM_TESTSUITE_VISION_SOURCE_FEEDER_H__ +#define __MV_DEPTHSTREAM_TESTSUITE_VISION_SOURCE_FEEDER_H__ + +#include "IFeeder.h" +#include + +class VisionSourceFeeder : public IFeeder +{ +private: + Mv3d * _mv3d; + int _state; + const int _deviceId; + + vision_source_h _handle; + vision_source_format_s _format; + + static int _vision_source_cb(vision_source_buffer_s *buffer, void *user_data); +public: + VisionSourceFeeder(int width, int height, int fps, int stereoFormat); + ~VisionSourceFeeder(); + + void start(std::shared_ptr mv3d) override; + void stop() override; +}; + +VisionSourceFeeder::VisionSourceFeeder(int width, int height, int fps, int stereoFormat) + : _mv3d(nullptr) + , _state(NONE) + , _deviceId(3) + , _handle(nullptr) +{ + vision_source_init(&_handle); + vision_source_open_device(_handle, _deviceId); + + _format.pixel_format = VISION_SOURCE_PIXEL_FORMAT_NV12; + _format.resolution = { width, height }, + _format.fps = fps; + _format.quality = 0; + _format.bitrate = 0; + + switch (stereoFormat) { + case STEREO_FORMAT_SIDE_BY_SIDE: + _format.resolution.width <<= 1; + break; + case STEREO_FORMAT_TOP_AND_BOTTOM: + _format.resolution.height <<= 1; + break; + default: + break; + } + + vision_source_set_stream_format(_handle, &_format); +}; + +VisionSourceFeeder::~VisionSourceFeeder() +{ + if (_handle) { + stop(); + } +}; + +void VisionSourceFeeder::start(std::shared_ptr mv3d) +{ + _mv3d = mv3d.get(); + _mv3d->resetTime(); + _state = OKAY; + vision_source_start_stream(_handle, _vision_source_cb, this); +} + +void VisionSourceFeeder::stop() +{ + _state = NONE; + vision_source_stop_stream(_handle); + vision_source_close_device(_handle); + vision_source_exit(_handle); + _handle = nullptr; +} + + +int VisionSourceFeeder::_vision_source_cb(vision_source_buffer_s *buffer, void *user_data) +{ + VisionSourceFeeder* visionSource = static_cast(user_data); + std::cout << "_vision_source_cb: " << visionSource->_mv3d->checkElapsedTime() << " ms" << std::endl; + if (visionSource->_state != OKAY) + return 0; + + visionSource->_mv3d->run(buffer); + return 0; +} +#endif \ No newline at end of file diff --git a/test/testsuites/mv3d/depthstream_test_suite.cpp b/test/testsuites/mv3d/depthstream_test_suite.cpp index 5cf54212..e38a98e4 100644 --- a/test/testsuites/mv3d/depthstream_test_suite.cpp +++ b/test/testsuites/mv3d/depthstream_test_suite.cpp @@ -34,13 +34,10 @@ #include #include -#include "mv_3d.h" +#include "Mv3d.h" + #include -#include -#include -#ifdef WITH_DA_PROFILE -#include -#endif +#include "FeederFactory.h" #include @@ -56,450 +53,79 @@ using namespace open3d; #endif -#define VISION_SOURCE_DEVICE_ID 3 - -class StopWatch -{ -private: - std::chrono::steady_clock::time_point start; -public: - StopWatch() = default; - ~StopWatch() = default; - - void resetTime() - { - start = std::chrono::steady_clock::now(); - } - std::chrono::milliseconds elapsedTime() - { - return std::chrono::duration_cast(std::chrono::steady_clock::now() - start); - } -}; - -enum { STEREO_FORMAT_NONE, STEREO_FORMAT_SIDE_BY_SIDE, STEREO_FORMAT_TOP_AND_BOTTOM }; -enum { VISION_SOURCE, CAMERA_SOURCE }; -enum { NONE, OKAY }; - -class Mv3d +class DfsApp { private: - bool _isAsync; - int _sourceWidth; - int _sourceHeight; - unsigned char *_rawBuffer; - - mv_3d_h _3dHandle; - mv_source_h _source; - mv_engine_config_h _engineConfig; - - int _state; - std::string _calibFilePath; - std::string _depthFilePath; - StopWatch _timer; - - static void _depth_stereo_cb(mv_source_h source, unsigned short *depth, unsigned int width, unsigned int height, - void *user_data) - { -#ifdef WITH_DA_PROFILE - std::cout << "_depth_stereo_cb: " << std::endl; - da_timestamp_s timestamp; - mv_source_get_timestamp(source, ×tamp); - std::cout << "timestamp [" << timestamp.timestamp << "], "; - std::cout << "ts_sof [" << timestamp.ts_sof << "], "; - std::cout << "ts_aux [" << timestamp.ts_aux << "], "; - std::cout << "ts_eof [" << timestamp.ts_eof << "], " << std::endl; -#endif - cv::Mat dump(cv::Size(width, height), CV_16U, depth); - dump.setTo(0, dump==65535); - - Mv3d* mv3d = static_cast(user_data); - cv::imwrite(mv3d->_depthFilePath, dump); - } + GMainLoop *_loop; + std::unique_ptr _feeder; + std::shared_ptr _mv3d; public: - Mv3d(int minDisparity, int maxDisparity, bool isAsync, std::string calibFilePath, int depthWidth, int depthHeight, int stereoFormat, std::string depthFilePath) - :_isAsync(isAsync) - , _sourceWidth(depthWidth) - , _sourceHeight(depthHeight) - , _rawBuffer(nullptr) - , _3dHandle(nullptr) - , _source(nullptr) - , _engineConfig(nullptr) - , _state(NONE) - , _calibFilePath("/usr/share/dfs-qcmv/stereoCalibDA.yaml") - , _depthFilePath("/tmp/depthDump.png") - { - // MediaVision mv_engine_config_h - mv_create_engine_config(&_engineConfig); - mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_WIDTH, depthWidth); - mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_HEIGHT, depthHeight); - mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_MIN_DISPARITY, minDisparity); - mv_engine_config_set_int_attribute(_engineConfig, MV_3D_DEPTH_MAX_DISPARITY, maxDisparity); - - if (!calibFilePath.empty()) - _calibFilePath = calibFilePath; - mv_engine_config_set_string_attribute(_engineConfig, MV_3D_DEPTH_STEREO_CONFIG_FILE_PATH, _calibFilePath.c_str()); - - if (!depthFilePath.empty()) - _depthFilePath = depthFilePath; - - // MediaVision mv_3d_h - mv_3d_create(&_3dHandle); - mv_3d_configure(_3dHandle, _engineConfig); - mv_3d_set_depth_cb(_3dHandle, _depth_stereo_cb, this); - - mv_create_source(&_source); - - switch (stereoFormat) { - case STEREO_FORMAT_SIDE_BY_SIDE: - _sourceWidth <<= 1; - break; - case STEREO_FORMAT_TOP_AND_BOTTOM: - _sourceHeight <<= 1; - break; - default: - break; - } - - _rawBuffer = new unsigned char [_sourceWidth * _sourceHeight]; - } - - ~Mv3d() - { - if (_engineConfig || _3dHandle || _source) - stop(); - } - - void prepare() - { - mv_3d_prepare(_3dHandle); - _state = OKAY; - } - - void run(vision_source_buffer_s *buffer) - { - if (_state != OKAY) - return; - - for (unsigned int h = 0; h < buffer->resolution.height; h++) { - memcpy(_rawBuffer + buffer->resolution.width * h, buffer->planes[0].data + (buffer->planes[0].align_width * h), - buffer->resolution.width); - } - - mv_source_fill_by_buffer(_source, _rawBuffer, _sourceWidth * _sourceHeight, - _sourceWidth, _sourceHeight, MEDIA_VISION_COLORSPACE_Y800); - -#ifdef WITH_DA_PROFILE - mv_source_set_timestamp(_source, static_cast(buffer->priv)); -#endif + DfsApp(); + ~DfsApp(); - if (_isAsync) - mv_3d_run_async(_3dHandle, _source, nullptr, nullptr); - else - mv_3d_run(_3dHandle, _source, nullptr, nullptr); - - mv_source_clear(_source); - } - - void run(media_packet_h pkt, unsigned long& timestamp, camera_frame_meta_s& meta) - { - mv_source_fill_by_media_packet(_source, pkt); - -#ifdef WITH_DA_PROFILE - da_timestamp_s daTimestamp = {timestamp, - meta.ts_soe, - meta.ts_eoe, - meta.ts_sof, - meta.ts_eof, - meta.ts_hal, - meta.ts_qmf, - meta.td_exp, - meta.ts_aux, - meta.td_aux, - meta.seqnum, - meta.flags }; - - mv_source_set_timestamp(_source, &daTimestamp); -#endif - mv_3d_run_async(_3dHandle, _source, nullptr, nullptr); - - mv_source_clear(_source); - } - - void stop() - { - _state = NONE; - delete [] _rawBuffer; - - if (_source) { - mv_destroy_source(_source); - _source = nullptr; - } - - if (_3dHandle) { - mv_3d_destroy(_3dHandle); - _3dHandle = nullptr; - } - - if (_engineConfig) { - mv_destroy_engine_config(_engineConfig); - _engineConfig = nullptr; - } - } - - void resetTime() - { - _timer.resetTime(); - } - - long long int checkElapsedTime() - { - return static_cast(_timer.elapsedTime().count()); - } + void createDfs(std::shared_ptr mv3d, std::unique_ptr feeder); + void start(); + void stop(); + static void helper(); }; -class IFeeder +DfsApp::DfsApp() + : _loop(nullptr) { -public: - virtual ~IFeeder(){}; - virtual void start(std::shared_ptr mv3d) = 0; - virtual void stop() = 0; -}; - -class VisionSourceFeeder : public IFeeder -{ -private: - Mv3d * _mv3d; - int _state; - const int _deviceId; - - vision_source_h _handle; - vision_source_format_s _format; - - static int _vision_source_cb(vision_source_buffer_s *buffer, void *user_data) - { - VisionSourceFeeder* visionSource = static_cast(user_data); - std::cout << "_vision_source_cb: " << visionSource->_mv3d->checkElapsedTime() << " ms" << std::endl; - if (visionSource->_state != OKAY) - return 0; - - visionSource->_mv3d->run(buffer); - return 0; - } -public: - VisionSourceFeeder(int width, int height, int fps, int stereoFormat) - : _mv3d(nullptr) - , _state(NONE) - , _deviceId(3) - , _handle(nullptr) - { - vision_source_init(&_handle); - vision_source_open_device(_handle, _deviceId); - - _format.pixel_format = VISION_SOURCE_PIXEL_FORMAT_NV12; - _format.resolution = { width, height }, - _format.fps = fps; - _format.quality = 0; - _format.bitrate = 0; - - switch (stereoFormat) { - case STEREO_FORMAT_SIDE_BY_SIDE: - _format.resolution.width <<= 1; - break; - case STEREO_FORMAT_TOP_AND_BOTTOM: - _format.resolution.height <<= 1; - break; - default: - break; - } - - vision_source_set_stream_format(_handle, &_format); - }; - - ~VisionSourceFeeder() - { - if (_handle) { - stop(); - } - }; - - void start(std::shared_ptr mv3d) override - { - _mv3d = mv3d.get(); - _mv3d->resetTime(); - _state = OKAY; - vision_source_start_stream(_handle, _vision_source_cb, this); - } - - void stop() override - { - _state = NONE; - vision_source_stop_stream(_handle); - vision_source_close_device(_handle); - vision_source_exit(_handle); - _handle = nullptr; - } -}; +} -class CameraSourceFeeder : public IFeeder +DfsApp::~DfsApp() { -private: - Mv3d* _mv3d; - const camera_device_e _deviceId; - - camera_h _handle; - camera_frame_meta_s _frameMeta; - - static void _camera_preview_cb(media_packet_h pkt, void *user_data) - { - CameraSourceFeeder* cameraSource = static_cast(user_data); - std::cout << "_camera_preview_cb: " << cameraSource->_mv3d->checkElapsedTime() << " ms" << std::endl; - - unsigned long timestamp; - camera_attr_get_preview_frame_timestamp(cameraSource->_handle, ×tamp); - camera_attr_get_preview_frame_meta(cameraSource->_handle, &cameraSource->_frameMeta); - cameraSource->_mv3d->run(pkt, timestamp, cameraSource->_frameMeta); - media_packet_unref(pkt); - } - - static bool _supported_preview_fps_cb(camera_attr_fps_e fps, void *user_data) - { - CameraSourceFeeder* cameraSource = static_cast(user_data); - if (fps == 10) { - std::cout << "Set desired camera preview fps: " << fps << std::endl; - camera_attr_set_preview_fps(cameraSource->_handle, fps); - return false; - } - return true; - } -public: - CameraSourceFeeder() - : _mv3d(nullptr) - , _deviceId(CAMERA_DEVICE_CAMERA3) - , _handle(nullptr) - { - camera_create(_deviceId, &_handle); - camera_attr_foreach_supported_fps(_handle, _supported_preview_fps_cb, this); - if (!camera_is_supported_media_packet_preview_cb(_handle)) - throw std::runtime_error("not supported media packet preview cb"); - } - - ~CameraSourceFeeder() - { + if (_loop) stop(); +} - camera_destroy(_handle); - _handle = nullptr; - }; - - void start(std::shared_ptr mv3d) override - { - _mv3d = mv3d.get(); - camera_set_media_packet_preview_cb(_handle, _camera_preview_cb, this); +void DfsApp::createDfs(std::shared_ptr mv3d, std::unique_ptr feeder) +{ + // Mv3d - mediavision dfs + _mv3d = mv3d; + _mv3d->prepare(); - mv3d->resetTime(); - camera_start_preview(_handle); - } + // loop + _loop = g_main_loop_new(nullptr, false); - void stop() override - { - camera_state_e state; - camera_get_state(_handle, &state); - if (state == CAMERA_STATE_PREVIEW) - camera_stop_preview(_handle); - } -}; + // SourceFeeder + _feeder = std::move(feeder); +} -class FeederFactory +void DfsApp::start() { -private: - FeederFactory() = delete; - FeederFactory(const FeederFactory&) = delete; -public: - static std::unique_ptr createVisionSourceFeeder(int width=640, int height=400, int fps=10, int stereoFormat=STEREO_FORMAT_TOP_AND_BOTTOM) - { - return std::make_unique(width, height, fps, stereoFormat); - } - - static std::unique_ptr createCameraSourceFeeder() - { - return std::make_unique(); - } -}; + _feeder->start(_mv3d); + g_main_loop_run(_loop); +} -class DfsApp +void DfsApp::stop() { -private: - GMainLoop *_loop; - std::unique_ptr _feeder; - std::shared_ptr _mv3d; -public: - DfsApp() : _loop(nullptr) {} + g_main_loop_quit(_loop); - ~DfsApp() - { - if (_loop) - stop(); + if (_loop) { + g_main_loop_unref(_loop); + _loop = nullptr; } - void createDfs(int minDisparity, int maxDisparity, bool isAsync, std::string calibFilePath = "", - int sourceSelection = VISION_SOURCE, int stereoFormat = STEREO_FORMAT_TOP_AND_BOTTOM, - int sourceWidth = 640, int sourceHeight = 400, std::string depthFilePath = "") - { - // Mv3d - mediavision dfs - _mv3d = std::make_shared(minDisparity, maxDisparity, isAsync, calibFilePath, sourceWidth, sourceHeight, stereoFormat, depthFilePath); - _mv3d->prepare(); + _feeder->stop(); - // loop - _loop = g_main_loop_new(nullptr, false); - - // SourceFeeder - switch (sourceSelection) { - case VISION_SOURCE: - _feeder = FeederFactory::createVisionSourceFeeder(sourceWidth, sourceHeight, 10, stereoFormat); - break; - case CAMERA_SOURCE: - _feeder = FeederFactory::createCameraSourceFeeder(); - break; - default: - throw std::runtime_error("invalid source"); - } - } - - void start() - { - _feeder->start(_mv3d); - g_main_loop_run(_loop); - } - - void stop() - { - g_main_loop_quit(_loop); - - if (_loop) { - g_main_loop_unref(_loop); - _loop = nullptr; - } - - _feeder->stop(); - - _mv3d->stop(); - } - - static void helper() - { - std::cout << "Usage:" << std::endl; - std::cout << "mv_depthstream_test_suite " << std::endl; - std::cout << "\t\t\t " << std::endl; - std::cout << "\t isAsync: 0: mv_3d_run(), 1: mv_3d_run_async()" << std::endl; - std::cout << "\t stereo format: 1: side-by-side, 2: top-and-bottom" << std::endl; - std::cout << "\t source: 0: vision-source, 2: camera" << std::endl; - std::cout << "\t ex: mv_depthstream_test_suite 1 8 96 640 400 2 1 /usr/share/dfs-qcmv/stereoCalibDA.yaml /tmp/camerasource.png" << std::endl; - std::cout << "or simply run:" << std::endl; - std::cout << "mv_depthstream_test_suite " << std::endl; - std::cout << "\tex: mv_depthstream_test_suite 1 8 96" << std::endl; - } + _mv3d->stop(); +} -}; +void DfsApp::helper() +{ + std::cout << "Usage:" << std::endl; + std::cout << "mv_depthstream_test_suite " << std::endl; + std::cout << "\t\t\t " << std::endl; + std::cout << "\t isAsync: 0: mv_3d_run(), 1: mv_3d_run_async()" << std::endl; + std::cout << "\t stereo format: 1: side-by-side, 2: top-and-bottom" << std::endl; + std::cout << "\t source: 0: vision-source, 1: camera" << std::endl; + std::cout << "\t ex: mv_depthstream_test_suite 1 8 96 640 400 2 1 /usr/share/dfs-qcmv/stereoCalibDA.yaml /tmp/camerasource.png" << std::endl; + std::cout << "or simply run:" << std::endl; + std::cout << "mv_depthstream_test_suite " << std::endl; + std::cout << "\tex: mv_depthstream_test_suite 1 8 96" << std::endl; +} static DfsApp gApp; @@ -530,28 +156,46 @@ int main(int argc, char *argv[]) bool isAsync = false; int minDisp = 8; int maxDisp = 96; - - if (argc >= 4) { + int camWidth = 640; + int camHeight = 400; + int stereoFormat = STEREO_FORMAT_TOP_AND_BOTTOM; + int sourceSelection = VISION_SOURCE; + std::string stereoConfigFile; + std::string dispResultFile; + + if (argc == 4) { isAsync = (atoi(argv[1]) != 0); // 0: mv_3d_run(), 1: mv_3d_run_async() minDisp = atoi(argv[2]); // 8 maxDisp = atoi(argv[3]); // 96 - } - - if (argc == 10) { - int camWidth = atoi(argv[4]); // 640 - int camHeight = atoi(argv[5]); // 400 - int stereoFormat = atoi(argv[6]); // 1: SIDE_BY_SIDE, 2: STEREO_FORMAT_TOP_AND_BOTTOM - int sourceSelection = (atoi(argv[7]) != 0); // 0: vision-source, 1: camera - std::string stereoConfigFile = argv[8]; - std::string dispResultFile = argv[9]; - - gApp.createDfs(minDisp, maxDisp, isAsync, stereoConfigFile, sourceSelection, stereoFormat, camWidth, camHeight, dispResultFile); - } else if (argc == 4) { - gApp.createDfs(minDisp, maxDisp, isAsync); + } else if (argc == 10) { + camWidth = atoi(argv[4]); // 640 + camHeight = atoi(argv[5]); // 400 + stereoFormat = atoi(argv[6]); // 1: SIDE_BY_SIDE, 2: STEREO_FORMAT_TOP_AND_BOTTOM + sourceSelection = (atoi(argv[7]) != 0); // 0: vision-source, 1: camera + stereoConfigFile = argv[8]; + dispResultFile = argv[9]; } else { gApp.helper(); return 0; } + + std::unique_ptr feeder; + switch (sourceSelection) { + case VISION_SOURCE: + feeder = FeederFactory::createVisionSourceFeeder(camWidth, camHeight, 10, stereoFormat); + break; + case CAMERA_SOURCE: + feeder = FeederFactory::createCameraSourceFeeder(); + break; + default: + throw std::runtime_error("invalid source"); + } + + std::shared_ptr mv3d = std::make_shared(minDisp, maxDisp, isAsync, stereoConfigFile, camWidth, camHeight, stereoFormat, dispResultFile); + + // gApp.createDfs(mv3d, feeder); + gApp.createDfs(mv3d, std::move(feeder)); + signal(SIGINT, gSigHandler); gApp.start(); } catch (const std::exception& e) {