* optimize the region operation of the rtsp module

This commit is contained in:
lxowalle
2024-07-15 13:45:16 +08:00
parent 3ddea51a94
commit 7ec48b6e5b
3 changed files with 206 additions and 8 deletions

View File

@@ -175,6 +175,13 @@ namespace maix::rtsp
*/
err::Err update_region(rtsp::Region &region);
/**
* @brief del region
* @return error code
* @maixpy maix.rtsp.Rtsp.del_region
*/
err::Err del_region(rtsp::Region *region);
/**
* @brief return region list
* @attention DO NOT ADD THIS FUNC TO MAIXPY
@@ -184,6 +191,34 @@ namespace maix::rtsp
return this->_region_list;
}
/**
* @brief Draw a rectangle on the canvas
* @param id region id
* @param x rectangle coordinate x
* @param y rectangle coordinate y
* @param width rectangle width
* @param height rectangle height
* @param color rectangle color
* @param thickness rectangle thickness. If you set it to -1, the rectangle will be filled.
* @return error code
* @maixpy maix.rtsp.Rtsp.draw_rect
*/
err::Err draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness = 1);
/**
* @brief Draw a string on the canvas
* @param id region id
* @param x string coordinate x
* @param y string coordinate y
* @param str string
* @param color string color
* @param size string size
* @param thickness string thickness
* @return error code
* @maixpy maix.rtsp.Rtsp.draw_string
*/
err::Err draw_string(int id, int x, int y, const char *str, image::Color color, int size = 16, int thickness = 1);
/**
* @brief Get timestamp
*/
@@ -199,6 +234,8 @@ namespace maix::rtsp
this->_timestamp += (ms - this->_last_ms);
this->_last_ms = ms;
}
private:
std::string _ip;
int _port;
@@ -209,9 +246,12 @@ namespace maix::rtsp
camera::Camera *_camera;
thread::Thread *_thread;
std::vector<rtsp::Region *> _region_list;
std::vector<bool> _region_used_list;
std::vector<int> _region_type_list; // 0, normal; 1, string; 2, rect
std::vector<bool> _region_update_flag;
uint64_t _timestamp;
uint64_t _last_ms;
int _region_max_number;
};
} // namespace maix::rtsp

View File

@@ -87,4 +87,13 @@ namespace maix::rtsp
err::Err Rtsp::update_region(rtsp::Region &region) {
return region.update_canvas();
}
err::Err Rtsp::draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness) {
return err::ERR_NOT_IMPL;
}
err::Err Rtsp::draw_string(int id, int x, int y, const char *str, image::Color color, int size, int thickness)
{
return err::ERR_NOT_IMPL;
}
}

View File

@@ -8,6 +8,7 @@
#include "maix_rtsp.hpp"
#include "maix_err.hpp"
#include "rtsp_server.h"
#include "maix_basic.hpp"
#include <dirent.h>
#include "sophgo_middleware.hpp"
@@ -38,7 +39,6 @@ namespace maix::rtsp
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!");
}
this->_id = rgn_id;
this->_width = width;
this->_height = height;
@@ -51,9 +51,9 @@ namespace maix::rtsp
}
Region::~Region() {
// if (mmf_del_region_channel(this->_id) < 0) {
// err::check_raise(err::ERR_RUNTIME, "mmf_del_region_unused_channel failed!");
// }
if (mmf_del_region_channel(this->_id) < 0) {
err::check_raise(err::ERR_RUNTIME, "mmf_del_region_unused_channel failed!");
}
}
image::Image *Region::get_canvas() {
@@ -132,6 +132,12 @@ namespace maix::rtsp
this->_bind_camera = false;
this->_is_start = false;
this->_thread = NULL;
this->_region_max_number = 16;
for (int i = 0; i < this->_region_max_number; i ++) {
this->_region_list.push_back(NULL);
this->_region_type_list.push_back(0);
this->_region_used_list.push_back(false);
}
char *new_ip = NULL;
if (this->_ip.size() != 0) {
@@ -304,15 +310,158 @@ namespace maix::rtsp
return NULL;
}
rtsp::Region *region = new rtsp::Region(x, y, width, height, format, this->_camera);
if (region) {
this->_region_list.push_back(region);
this->_region_update_flag.push_back(false);
// Find unused idx
int unused_idx = -1;
for (int i = 0; i < this->_region_max_number; i ++) {
if (this->_region_used_list[i] == false) {
unused_idx = i;
break;
}
}
err::check_bool_raise(unused_idx != -1, "Unused region not found");
// Create region
rtsp::Region *region = new rtsp::Region(x, y, width, height, format, this->_camera);
err::check_null_raise(region, "Create region failed!");
this->_region_list[unused_idx] = region;
this->_region_used_list[unused_idx] = true;
this->_region_type_list[unused_idx] = 0;
return region;
}
err::Err Rtsp::update_region(rtsp::Region &region) {
return region.update_canvas();
}
err::Err Rtsp::del_region(rtsp::Region *region) {
err::check_null_raise(region, "The region object is NULL");
for (int i = 0; i < this->_region_max_number; i ++) {
if (this->_region_list[i] == region) {
this->_region_list[i] = NULL;
this->_region_used_list[i] = false;
this->_region_type_list[i] = 0;
delete region;
return err::ERR_NONE;
}
}
return err::ERR_NONE;
}
err::Err Rtsp::draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness)
{
// Check id
if (id < 0 || id > 3) {
log::error("region id is invalid! range is [0, 3");
err::check_raise(err::ERR_RUNTIME, "invalid parameter");
}
if (x < 0) {
width = width + x < 0 ? 0 : width + x;
x = 0;
}
if (y < 0) {
height = height + y < 0 ? 0 : height + y;
y = 0;
}
if (x > this->_camera->width()) {
x = 0;
width = 0;
}
if (y > this->_camera->height()) {
y = 0;
height = 0;
}
if (x + width > this->_camera->width()) {
width = this->_camera->width() - x;
}
if (y + height > this->_camera->height()) {
height = this->_camera->height() - y;
}
// Check if the region [id, id + 4) is used for other functions
for (size_t i = id; i < this->_region_used_list.size() && (int)i < id + 4; i ++) {
if (_region_used_list[i] == true && _region_type_list[i] != 2) {
log::error("In areas %d - %d, %d is used for other functions(%d)", id, id + 4, i, _region_type_list[i]);
err::check_raise(err::ERR_RUNTIME, "invalid parameter");
}
}
// Delete last region
for (size_t i = id; i < this->_region_used_list.size() && (int)i < id + 4; i ++) {
if (_region_used_list[i] == true && _region_type_list[i] == 2) {
delete _region_list[i];
_region_list[i] = NULL;
_region_used_list[i] = false;
_region_type_list[i] = -1;
}
}
// Create upper region
int upper_lower_height = 0;
upper_lower_height = thickness > 0 ? thickness : height;
upper_lower_height = upper_lower_height > height ? height : upper_lower_height;
rtsp::Region *region_upper = add_region(x, y, width, upper_lower_height);
err::check_null_raise(region_upper);
// Create lower region
rtsp::Region *region_lower = add_region(x, y + height - upper_lower_height, width, upper_lower_height);
err::check_null_raise(region_upper);
// Create left region
int left_right_width = 0;
left_right_width = thickness > 0 ? thickness : width;
left_right_width = left_right_width > width ? width : left_right_width;
rtsp::Region *region_left = add_region(x, y + upper_lower_height, left_right_width, height - 2 * upper_lower_height);
err::check_null_raise(region_left);
// Create right region
rtsp::Region *region_right = add_region(x + width - left_right_width, y + upper_lower_height, left_right_width, height - 2 * upper_lower_height);
err::check_null_raise(region_right);
// Config region list
_region_list[id] = region_upper;
_region_list[id + 1] = region_lower;
_region_list[id + 2] = region_left;
_region_list[id + 3] = region_right;
_region_used_list[id] = true;
_region_used_list[id + 1] = true;
_region_used_list[id + 2] = true;
_region_used_list[id + 3] = true;
_region_type_list[id] = 2;
_region_type_list[id + 1] = 2;
_region_type_list[id + 2] = 2;
_region_type_list[id + 3] = 2;
// Draw all of region
uint32_t color_hex = color.hex();
for (int i = id; i < id + 4; i ++) {
rtsp::Region *region = _region_list[i];
image::Image *img = region->get_canvas();
err::check_null_raise(img, "Get canvas image failed!");
uint32_t *data = (uint32_t *)img->data();
int width = img->width();
int height = img->height();
for (int i = 0; i < height; i ++) {
for (int j = 0; j < width; j ++) {
data[i * width + j] = color_hex;
}
}
update_region(*region);
}
return err::ERR_NONE;
}
err::Err Rtsp::draw_string(int id, int x, int y, const char *str, image::Color color, int size, int thickness)
{
return err::ERR_NOT_IMPL;
}
}