diff --git a/components/maixcam_lib/include/sophgo_middleware.hpp b/components/maixcam_lib/include/sophgo_middleware.hpp index 64202dbb..2d69040f 100644 --- a/components/maixcam_lib/include/sophgo_middleware.hpp +++ b/components/maixcam_lib/include/sophgo_middleware.hpp @@ -16,10 +16,15 @@ extern "C" { #include "cvi_sns_ctrl.h" #include "cvi_ive.h" #include "cvi_sys.h" +#include "sample_comm.h" #ifdef __cplusplus } #endif +#define MMF_FUNC_SET_PARAM(method, num) ((uint32_t)((((uint32_t)method) << 24) | (num & 0xff))) +#define MMF_FUNC_GET_PARAM_METHOD(x) ((x >> 24) & 0xffffff) +#define MMF_FUNC_GET_PARAM_NUM(x) ((x & 0xff)) + typedef struct { uint8_t *data[8]; int data_size[8]; @@ -100,7 +105,6 @@ int mmf_vi_deinit(void); int mmf_vi_get_max_size(int *width, int *height); int mmf_vi_chn_caculate_ldc(int ch, int x_ratio, int y_ratio, int center_x_oft, int center_y_oft, int distortion_ratio); int mmf_vi_chn_ldc_enable(int ch, bool en); -int mmf_add_vi_channel_with_enc(int ch, int width, int height, int format); int mmf_add_vi_channel(int ch, int width, int height, int format); int mmf_del_vi_channel(int ch); int mmf_del_vi_channel_all(void); @@ -221,4 +225,46 @@ int mmf_vdec_push(int ch, uint8_t *data, int size, uint8_t is_start, uint8_t is_ int mmf_vdec_pop(int ch, void **data, int *len, int *width, int *height, int *format); int mmf_vdec_free(int ch); int mmf_vdec_get_cfg(int ch, mmf_vdec_cfg_t *cfg); + +int mmf_init0(uint32_t param, ...); +int mmf_deinit0(uint32_t param, ...); +int mmf_vi_init0(uint32_t param, ...); +int mmf_add_vi_channel0(uint32_t param, ...); +int mmf_add_vo_channel0(uint32_t param, ...); +int mmf_add_region_channel0(uint32_t param, ...); +int mmf_add_venc_channel0(uint32_t param, ...); +int mmf_add_vdec_channel0(uint32_t param, ...); + +static inline int mmf_init_v2(int reload_kmod) { + return mmf_init0(MMF_FUNC_SET_PARAM(0, 1), reload_kmod); +} + +static inline int mmf_deinit_v2(int force) { + return mmf_deinit0(MMF_FUNC_SET_PARAM(0, 1), force); +} + +static inline int mmf_vi_init_v2(int width, int height, int vi_format, int vpss_format, int fps, int pool_num, SAMPLE_VI_CONFIG_S *vi_cfg) { + return mmf_vi_init0(MMF_FUNC_SET_PARAM(0, 8), width, height, vi_format, vpss_format, fps, pool_num, vi_cfg); +} + +static inline int mmf_add_vi_channel_v2(int ch, int width, int height, int format, int fps, int depth, int mirror, int vflip, int fit, int pool_num) { + return mmf_add_vi_channel0(MMF_FUNC_SET_PARAM(0, 10), ch, width, height, format, fps, depth, mirror, vflip, fit, pool_num); +} + +static inline int mmf_add_vo_channel_v2(int layer, int ch, int width, int height, int format_in, int format_out, int fps, int depth, int mirror, int vflip, int fit, int rotate, int pool_num_in, int pool_num_out) { + return mmf_add_vo_channel0(MMF_FUNC_SET_PARAM(0, 14), layer, ch, width, height, format_in, format_out, fps, depth, mirror, vflip, fit, rotate, pool_num_in, pool_num_out); +} + +static inline int mmf_add_region_channel_v2(int ch, int type, int mod_id, int dev_id, int chn_id, int x, int y, int width, int height, int format) { + return mmf_add_region_channel0(MMF_FUNC_SET_PARAM(0, 10), ch, type, mod_id, dev_id, chn_id, x, y, width, height, format); +} + +static inline int mmf_add_venc_channel_v2(int ch, void *cfg) { + return mmf_add_venc_channel0(MMF_FUNC_SET_PARAM(0, 2), ch, cfg); +} + +static inline int mmf_add_vdec_channel_v2(int ch, void *cfg) { + return mmf_add_vdec_channel0(MMF_FUNC_SET_PARAM(0, 2), ch, cfg); +} + #endif // __SOPHGO_MIDDLEWARE_HPP__ diff --git a/components/vision/port/maixcam/maix_camera_mmf.cpp b/components/vision/port/maixcam/maix_camera_mmf.cpp index 81c3d8e1..2c59f765 100644 --- a/components/vision/port/maixcam/maix_camera_mmf.cpp +++ b/components/vision/port/maixcam/maix_camera_mmf.cpp @@ -15,6 +15,48 @@ #define MMF_SENSOR_NAME "MMF_SENSOR_NAME" // Setting the sensor name will be used to select which driver to use #define MAIX_SENSOR_FPS "MAIX_SENSOR_FPS" // Set the frame rate, whether it takes effect or not is determined by the driver #define MMF_INIT_DO_NOT_RELOAD_KMOD "MMF_INIT_DO_NOT_RELOAD_KMOD" // Disable reloading of kmod on mmf_init + +static void try_deinit_mmf() +{ + static uint8_t is_called = 0; + if (!is_called) { + mmf_deinit_v2(true); + is_called = 1; + } +} + +static void signal_handle(int signal) +{ + const char *signal_msg = NULL; + switch (signal) { + case SIGILL: signal_msg = "SIGILL"; break; + case SIGTRAP: signal_msg = "SIGTRAP"; break; + case SIGABRT: signal_msg = "SIGABRT"; break; + case SIGBUS: signal_msg = "SIGBUS"; break; + case SIGFPE: signal_msg = "SIGFPE"; break; + case SIGKILL: signal_msg = "SIGKILL"; break; + case SIGSEGV: signal_msg = "SIGSEGV"; break; + default: signal_msg = "UNKNOWN"; break; + } + + maix::log::error("Trigger signal, code:%s(%d)!\r\n", signal_msg, signal); + try_deinit_mmf(); + exit(1); +} + +static __attribute__((constructor)) void maix_vision_register_signal(void) +{ + signal(SIGILL, signal_handle); + signal(SIGTRAP, signal_handle); + signal(SIGABRT, signal_handle); + signal(SIGBUS, signal_handle); + signal(SIGFPE, signal_handle); + signal(SIGKILL, signal_handle); + signal(SIGSEGV, signal_handle); + + maix::util::register_exit_function(try_deinit_mmf); +} + namespace maix::camera { static bool set_regs_flag = false; @@ -265,6 +307,90 @@ namespace maix::camera fclose(file); return poolIdCount; } + + static int _mmf_vi_init(int width, int height, int fps) + { + SIZE_S stSize; + PIC_SIZE_E enPicSize; + SAMPLE_INI_CFG_S stIniCfg; + SAMPLE_VI_CONFIG_S stViConfig; + PIXEL_FORMAT_E vi_format; + PIXEL_FORMAT_E vi_vpss_format; + mmf_sys_cfg_t sys_cfg = {0}; + + // config vi param + char *sensor_name = getenv(MMF_SENSOR_NAME); + err::check_null_raise(sensor_name, "sensor name not found!"); + err::check_bool_raise(!SAMPLE_COMM_VI_ParseIni(&stIniCfg), "sensor cfg parse complete!"); + err::check_bool_raise(stIniCfg.devNum != 0, "Not device found! devnum = 0"); + + if (!strcmp(sensor_name, "sms_sc035gs")) { + sys_cfg.vb_pool[0].size = 640 * 480 * 3 / 2; + sys_cfg.vb_pool[0].count = 3; + sys_cfg.vb_pool[0].map = 2; + sys_cfg.max_pool_cnt = 1; + + stIniCfg.enSnsType[0] = SMS_SC035GS_MIPI_480P_120FPS_12BIT; + stIniCfg.as8PNSwap[0][0] = 0; + stIniCfg.as8PNSwap[0][1] = 0; + stIniCfg.as8PNSwap[0][2] = 0; + stIniCfg.as8PNSwap[0][3] = 0; + stIniCfg.as8PNSwap[0][4] = 0; + vi_format = PIXEL_FORMAT_NV21; + vi_vpss_format = PIXEL_FORMAT_YUV_400; + } else if (!strcmp(sensor_name, "ov_ov2685")) { + sys_cfg.vb_pool[0].size = 1600 * 1200 * 3 / 2; + sys_cfg.vb_pool[0].count = 3; + sys_cfg.vb_pool[0].map = 2; + sys_cfg.max_pool_cnt = 1; + + stIniCfg.enSnsType[0] = GCORE_OV2685_MIPI_1600x1200_30FPS_10BIT; + stIniCfg.as8PNSwap[0][0] = 1; + stIniCfg.as8PNSwap[0][1] = 1; + stIniCfg.as8PNSwap[0][2] = 1; + stIniCfg.as8PNSwap[0][3] = 0; + stIniCfg.as8PNSwap[0][4] = 0; + vi_format = PIXEL_FORMAT_NV21; + vi_vpss_format = PIXEL_FORMAT_NV21; + } else { // default is gcore_gc4653 + if (width <= 1280 && height <= 720 && fps > 30) { + sys_cfg.vb_pool[0].size = 1280 * 720 * 3 / 2; + sys_cfg.vb_pool[0].count = 3; + sys_cfg.vb_pool[0].map = 2; + sys_cfg.max_pool_cnt = 1; + } else { + sys_cfg.vb_pool[0].size = 2560 * 1440 * 3 / 2; + sys_cfg.vb_pool[0].count = 2; + sys_cfg.vb_pool[0].map = 2; + sys_cfg.max_pool_cnt = 1; + } + + if (width <= 1280 && height <= 720 && fps > 30) { + stIniCfg.enSnsType[0] = GCORE_GC4653_MIPI_720P_60FPS_10BIT; + } else { + stIniCfg.enSnsType[0] = GCORE_GC4653_MIPI_4M_30FPS_10BIT; + } + stIniCfg.as8PNSwap[0][0] = 0; + stIniCfg.as8PNSwap[0][1] = 0; + stIniCfg.as8PNSwap[0][2] = 0; + stIniCfg.as8PNSwap[0][3] = 0; + stIniCfg.as8PNSwap[0][4] = 0; + vi_format = PIXEL_FORMAT_NV21; + vi_vpss_format = PIXEL_FORMAT_NV21; + } + + mmf_pre_config_sys(&sys_cfg); + err::check_bool_raise(!mmf_init_v2(false), "mmf init failed"); + err::check_bool_raise(!SAMPLE_COMM_VI_IniToViCfg(&stIniCfg, &stViConfig), "IniToViCfg failed!"); + err::check_bool_raise(!SAMPLE_COMM_VI_GetSizeBySensor(stIniCfg.enSnsType[0], &enPicSize), "GetSizeBySensor failed!"); + err::check_bool_raise(!SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize), "GetPicSize failed!"); + if (0 != mmf_vi_init_v2(stSize.u32Width, stSize.u32Height, vi_format, vi_vpss_format, fps, 3, &stViConfig)) { + mmf_deinit_v2(false); + err::check_raise(err::ERR_RUNTIME, "mmf vi init failed"); + } + return 0; + } + err::Err Camera::open(int width, int height, image::Format format, int fps, int buff_num) { int width_tmp = (width == -1) ? _width : width; @@ -324,56 +450,11 @@ namespace maix::camera _config_sensor_env(_fps); // mmf init - mmf_sys_cfg_t sys_cfg = {0}; - char *sensor_name = getenv(MMF_SENSOR_NAME); - err::check_null_raise(sensor_name, "sensor name not found!"); - if (!strcmp(sensor_name, "gcore_gc4653")) { - if (_width <= 1280 && _height <= 720 && _fps > 30) { - sys_cfg.vb_pool[0].size = 1280 * 720 * 3 / 2; - sys_cfg.vb_pool[0].count = 3; - sys_cfg.vb_pool[0].map = 2; - sys_cfg.max_pool_cnt = 1; - } else { - sys_cfg.vb_pool[0].size = 2560 * 1440 * 3 / 2; - sys_cfg.vb_pool[0].count = 2; - sys_cfg.vb_pool[0].map = 2; - sys_cfg.max_pool_cnt = 1; - } - } else if ((!strcmp(sensor_name, "sms_sc035gs"))) { - sys_cfg.vb_pool[0].size = 640 * 480 * 3 / 2; - sys_cfg.vb_pool[0].count = 3; - sys_cfg.vb_pool[0].map = 2; - sys_cfg.max_pool_cnt = 1; - } else if ((!strcmp(sensor_name, "ov_ov2685"))) { - sys_cfg.vb_pool[0].size = 1600 * 1200 * 3 / 2; - sys_cfg.vb_pool[0].count = 3; - sys_cfg.vb_pool[0].map = 2; - sys_cfg.max_pool_cnt = 1; - } else { - log::error("sensor name not found! name:%s", sensor_name); - err::check_raise(err::ERR_RUNTIME, "sensor name not found!"); - } - mmf_pre_config_sys(&sys_cfg); - err::check_bool_raise(!mmf_init(), "mmf init failed"); - - mmf_pre_config_sys(&sys_cfg); - err::check_bool_raise(!mmf_init(), "mmf init failed"); - - mmf_vi_cfg_t cfg = {0}; - cfg.w = _width; - cfg.h = _height; - cfg.fmt = mmf_invert_format_to_mmf(_format_impl); - cfg.depth = _buff_num; - cfg.fps = _fps; - if (0 != mmf_vi_init2(&cfg)) { - mmf_deinit(); - err::check_raise(err::ERR_RUNTIME, "mmf vi init failed"); - } - + err::check_bool_raise(!_mmf_vi_init(_width, _height, _fps), "mmf vi init failed"); err::check_bool_raise((_ch = mmf_get_vi_unused_channel()) >= 0, "mmf get vi channel failed"); - if (0 != mmf_add_vi_channel(_ch, _width, _height, mmf_invert_format_to_mmf(_format_impl))) { + if (0 != mmf_add_vi_channel_v2(_ch, _width, _height, mmf_invert_format_to_mmf(_format_impl), _fps, 2, -1, -1, 2, 3)) { mmf_vi_deinit(); - mmf_deinit(); + mmf_deinit_v2(false); err::check_raise(err::ERR_RUNTIME, "mmf add vi channel failed"); } @@ -392,7 +473,7 @@ namespace maix::camera } } - mmf_deinit(); + mmf_deinit_v2(false); } camera::Camera *Camera::add_channel(int width, int height, image::Format format, int fps, int buff_num, bool open) diff --git a/components/vision/port/maixcam/maix_display_mmf.hpp b/components/vision/port/maixcam/maix_display_mmf.hpp index 0ff3e351..554a297d 100644 --- a/components/vision/port/maixcam/maix_display_mmf.hpp +++ b/components/vision/port/maixcam/maix_display_mmf.hpp @@ -110,7 +110,7 @@ namespace maix::display || _format == image::FMT_YVU420SP || _format == image::FMT_BGRA8888, "Format not support"); - if (0 != mmf_init()) { + if (0 != mmf_init_v2(true)) { err::check_raise(err::ERR_RUNTIME, "mmf init failed"); } int pwm_id = 10; @@ -131,7 +131,7 @@ namespace maix::display // layer 1 means osd layer err::check_bool_raise(_format == image::FMT_BGRA8888, "Format not support"); - if (0 != mmf_init()) { + if (0 != mmf_init_v2(true)) { err::check_raise(err::ERR_RUNTIME, "mmf init failed"); } int pwm_id = 10; @@ -141,7 +141,7 @@ namespace maix::display ~DisplayCviMmf() { mmf_del_vo_channel(this->_layer, this->_ch); - mmf_deinit(); + mmf_deinit_v2(false); if(_bl_pwm) { delete _bl_pwm; @@ -183,8 +183,15 @@ namespace maix::display return err::ERR_RUNTIME; } - if (0 != mmf_add_vo_channel_with_fit(this->_layer, ch, width, height, mmf_invert_format_to_mmf(format), 2)) { - log::error("mmf_add_vo_channel_with_fit failed\n"); + int mmf_format_out = PIXEL_FORMAT_NV21; + image::Format format_out = (image::Format)mmf_invert_format_to_maix(mmf_format_out); + size_t image_size = image::fmt_size[format_out]; + int pool_num_out = 1; + if (width * height * image_size > 1920 * 1080 * image_size) { + pool_num_out = 2; + } + if (0 != mmf_add_vo_channel_v2(this->_layer, ch, width, height, mmf_invert_format_to_mmf(format), mmf_format_out, -1, 0, -1, -1, 0, 90, 2, pool_num_out)) { + log::error("mmf_add_vo_channel_v2 failed\n"); return err::ERR_RUNTIME; } diff --git a/components/vision/port/maixcam/maix_rtmp_maixcam.cpp b/components/vision/port/maixcam/maix_rtmp_maixcam.cpp index f23564de..25c51f98 100644 --- a/components/vision/port/maixcam/maix_rtmp_maixcam.cpp +++ b/components/vision/port/maixcam/maix_rtmp_maixcam.cpp @@ -145,7 +145,7 @@ namespace maix::rtmp { throw std::runtime_error("create lock failed!"); } - if (0 != mmf_init()) { + if (0 != mmf_init_v2(true)) { err::check_raise(err::ERR_RUNTIME, "init mmf failed!"); } @@ -170,7 +170,7 @@ namespace maix::rtmp { socket_close(_socket); socket_cleanup(); - mmf_deinit(); + mmf_deinit_v2(false); pthread_mutex_destroy(&_lock); } @@ -326,7 +326,7 @@ namespace maix::rtmp { }; - if (0 != mmf_add_venc_channel(MMF_VENC_CHN, &cfg)) { + if (0 != mmf_add_venc_channel_v2(MMF_VENC_CHN, &cfg)) { err::check_raise(err::ERR_RUNTIME, "mmf venc init failed!"); } @@ -453,7 +453,7 @@ namespace maix::rtmp { cfg.w = img_w; cfg.h = img_h; cfg.fmt = mmf_invert_format_to_mmf(mmf_fmt); - if (0 != mmf_add_venc_channel(MMF_VENC_CHN, &cfg)) { + if (0 != mmf_add_venc_channel_v2(MMF_VENC_CHN, &cfg)) { err::check_raise(err::ERR_RUNTIME, "mmf venc init failed!\r\n"); } } diff --git a/components/vision/port/maixcam/maix_rtsp_maixcam.cpp b/components/vision/port/maixcam/maix_rtsp_maixcam.cpp index a97ac50d..77593347 100644 --- a/components/vision/port/maixcam/maix_rtsp_maixcam.cpp +++ b/components/vision/port/maixcam/maix_rtsp_maixcam.cpp @@ -36,8 +36,8 @@ namespace maix::rtsp int vi_vpss = 0; int vi_vpss_chn = camera->get_channel(); - if (0 != mmf_add_region_channel(rgn_id, 0, 6, vi_vpss, vi_vpss_chn, x2, y2, width, height, mmf_invert_format_to_mmf(format))) { - err::check_raise(err::ERR_RUNTIME, "mmf_add_region_channel failed!"); + if (0 != mmf_add_region_channel_v2(rgn_id, 0, 6, vi_vpss, vi_vpss_chn, x2, y2, width, height, mmf_invert_format_to_mmf(format))) { + err::check_raise(err::ERR_RUNTIME, "mmf_add_region_channel_v2 failed!"); } this->_id = rgn_id; this->_width = width; diff --git a/components/vision/port/maixcam/maix_video_mmf.cpp b/components/vision/port/maixcam/maix_video_mmf.cpp index fa629bf1..7fc78206 100644 --- a/components/vision/port/maixcam/maix_video_mmf.cpp +++ b/components/vision/port/maixcam/maix_video_mmf.cpp @@ -48,12 +48,12 @@ namespace maix::video switch (_type) { case VIDEO_H265_CBR: { - if (0 != mmf_init()) { + if (0 != mmf_init_v2(true)) { err::check_raise(err::ERR_RUNTIME, "init mmf failed!"); } if (0 != mmf_enc_h265_init(MMF_VENC_CHN, _width, _height)) { - mmf_deinit(); + mmf_deinit_v2(false); err::check_raise(err::ERR_RUNTIME, "init mmf enc failed!"); } break; @@ -72,12 +72,12 @@ namespace maix::video .bitrate = _bitrate / 1000, }; - if (0 != mmf_init()) { + if (0 != mmf_init_v2(true)) { err::check_raise(err::ERR_RUNTIME, "init mmf failed!"); } - if (0 != mmf_add_venc_channel(MMF_VENC_CHN, &cfg)) { - mmf_deinit(); + if (0 != mmf_add_venc_channel_v2(MMF_VENC_CHN, &cfg)) { + mmf_deinit_v2(false); err::check_raise(err::ERR_RUNTIME, "mmf venc init failed!"); } break; @@ -164,7 +164,7 @@ namespace maix::video cfg.w = img_w; cfg.h = img_h; cfg.fmt = mmf_invert_format_to_mmf(img_fmt); - if (0 != mmf_add_venc_channel(MMF_VENC_CHN, &cfg)) { + if (0 != mmf_add_venc_channel_v2(MMF_VENC_CHN, &cfg)) { err::check_raise(err::ERR_RUNTIME, "mmf venc init failed!\r\n"); } _width = img_w; @@ -336,7 +336,7 @@ namespace maix::video cfg.w = img_w; cfg.h = img_h; cfg.fmt = mmf_invert_format_to_mmf(mmf_fmt); - if (0 != mmf_add_venc_channel(MMF_VENC_CHN, &cfg)) { + if (0 != mmf_add_venc_channel_v2(MMF_VENC_CHN, &cfg)) { err::check_raise(err::ERR_RUNTIME, "mmf venc init failed!\r\n"); } _width = img_w; diff --git a/projects/app_camera/main/app/app.cpp b/projects/app_camera/main/app/app.cpp index 0f3f5f0b..5b055100 100644 --- a/projects/app_camera/main/app/app.cpp +++ b/projects/app_camera/main/app/app.cpp @@ -507,6 +507,7 @@ int app_loop(maix::camera::Camera &camera, maix::image::Image *img, maix::displa system(cmd); snprintf(cmd, sizeof(cmd), "rm %s", priv.video_save_path.c_str()); system(cmd); + system("sync"); } priv.video_stop_flag = false;