|
@@ -4,7 +4,7 @@
|
|
|
* @Autor: lishengyin
|
|
|
* @Date: 2021-10-13 09:35:37
|
|
|
* @LastEditors: lishengyin
|
|
|
- * @LastEditTime: 2022-07-14 09:59:36
|
|
|
+ * @LastEditTime: 2022-07-20 11:05:47
|
|
|
*/
|
|
|
#include "inference.h"
|
|
|
#include "Notices.h"
|
|
@@ -13,10 +13,6 @@
|
|
|
#include <gst/rtsp/gstrtsptransport.h>
|
|
|
#include <gst/rtp/gstrtcpbuffer.h>
|
|
|
|
|
|
-#define MAX_DISPLAY_LEN 64
|
|
|
-
|
|
|
-#define PGIE_CLASS_ID_VEHICLE 0
|
|
|
-#define PGIE_CLASS_ID_PERSON 2
|
|
|
|
|
|
/* By default, OSD process-mode is set to CPU_MODE. To change mode, set as:
|
|
|
* 1: GPU mode (for Tesla only)
|
|
@@ -30,12 +26,12 @@
|
|
|
/* The muxer output resolution must be set if the input streams will be of
|
|
|
* different resolution. The muxer will scale all the input frames to this
|
|
|
* resolution. */
|
|
|
-#define MUXER_OUTPUT_WIDTH 1920
|
|
|
-#define MUXER_OUTPUT_HEIGHT 1080
|
|
|
+#define MUXER_OUTPUT_WIDTH 1280
|
|
|
+#define MUXER_OUTPUT_HEIGHT 720
|
|
|
|
|
|
/* Muxer batch formation timeout, for e.g. 40 millisec. Should ideally be set
|
|
|
* based on the fastest source's framerate. */
|
|
|
-#define MUXER_BATCH_TIMEOUT_USEC 5000
|
|
|
+#define MUXER_BATCH_TIMEOUT_USEC 1000000 / 60
|
|
|
|
|
|
#define TILED_OUTPUT_WIDTH 1280
|
|
|
#define TILED_OUTPUT_HEIGHT 720
|
|
@@ -46,107 +42,105 @@
|
|
|
|
|
|
#define MAX_NUM_SOURCES 30
|
|
|
|
|
|
-gint frame_number = 0;
|
|
|
-
|
|
|
-gint g_num_sources = 0;
|
|
|
gint g_source_id_list[MAX_NUM_SOURCES];
|
|
|
-gboolean g_eos_list[MAX_NUM_SOURCES];
|
|
|
gboolean g_source_enabled[MAX_NUM_SOURCES];
|
|
|
|
|
|
GMutex eos_lock;
|
|
|
-
|
|
|
GstElement *g_streammux = NULL;
|
|
|
std::shared_ptr<InferInfo> g_InferInfo = NULL;
|
|
|
-
|
|
|
-map<string, map<int, queue<std::shared_ptr<cv::Mat>>>> m_frames;
|
|
|
-
|
|
|
std::vector<cv::Scalar> colors_;
|
|
|
-
|
|
|
#define MAX_SINK_BINS (1024)
|
|
|
-
|
|
|
static guint server_count = 0;
|
|
|
-
|
|
|
static GstRTSPServer *server [MAX_SINK_BINS];
|
|
|
static GMutex server_cnt_lock;
|
|
|
|
|
|
-static gboolean
|
|
|
-start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num, guint64 udp_buffer_size)
|
|
|
-{
|
|
|
- GstRTSPMountPoints *mounts;
|
|
|
- GstRTSPMediaFactory *factory;
|
|
|
- char udpsrc_pipeline[512];
|
|
|
- char port_num_Str[64] = { 0 };
|
|
|
-
|
|
|
- if (udp_buffer_size == 0)
|
|
|
- udp_buffer_size = 512 * 1024;
|
|
|
-
|
|
|
- sprintf (udpsrc_pipeline,
|
|
|
- "( udpsrc name=pay0 port=%d buffer-size=%lu caps=\"application/x-rtp, media=video, "
|
|
|
- "clock-rate=90000, encoding-name=%s, payload=96 \" )",
|
|
|
- updsink_port_num, udp_buffer_size, "H264");
|
|
|
-
|
|
|
- sprintf (port_num_Str, "%d", rtsp_port_num);
|
|
|
-
|
|
|
- g_mutex_lock (&server_cnt_lock);
|
|
|
-
|
|
|
- server [server_count] = gst_rtsp_server_new ();
|
|
|
- g_object_set (server [server_count], "service", port_num_Str, NULL);
|
|
|
-
|
|
|
- mounts = gst_rtsp_server_get_mount_points (server [server_count]);
|
|
|
-
|
|
|
- factory = gst_rtsp_media_factory_new ();
|
|
|
- gst_rtsp_media_factory_set_launch (factory, udpsrc_pipeline);
|
|
|
-
|
|
|
- gst_rtsp_mount_points_add_factory (mounts, "/ds-test", factory);
|
|
|
-
|
|
|
- g_object_unref (mounts);
|
|
|
-
|
|
|
- gst_rtsp_server_attach (server [server_count], NULL);
|
|
|
-
|
|
|
- server_count++;
|
|
|
-
|
|
|
- g_mutex_unlock (&server_cnt_lock);
|
|
|
-
|
|
|
- g_print
|
|
|
- ("\n *** DeepStream: Launched RTSP Streaming at rtsp://localhost:%d/ds-test ***\n\n",
|
|
|
- rtsp_port_num);
|
|
|
+namespace gsd_ds{
|
|
|
|
|
|
- return TRUE;
|
|
|
-}
|
|
|
+ // m_Inference
|
|
|
+ std::shared_ptr<Inference> m_Inference = nullptr;
|
|
|
|
|
|
-// Keep 2 digits after decimal
|
|
|
-static std::string FloatToString(float number) {
|
|
|
- char buffer[10];
|
|
|
- snprintf(buffer, sizeof(buffer), "%.2f", number);
|
|
|
- return std::string(buffer);
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * @description: 构造
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ Inference::Inference(){}
|
|
|
|
|
|
-namespace gsd_ds{
|
|
|
- ThreadPool pool(4,ThreadPool::PRIORITY_HIGHEST, false);
|
|
|
- std::shared_ptr<Inference> m_Inference = nullptr;
|
|
|
- Inference::Inference()
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * @description: 析构
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
Inference::~Inference()
|
|
|
{
|
|
|
DebugL << "Returned, stopping playback" << endl;
|
|
|
- // GstState state;
|
|
|
- GstStateChangeReturn state_return;
|
|
|
- g_main_loop_quit (this->loop);
|
|
|
- state_return = gst_element_set_state(this->pipeline, GST_STATE_NULL);
|
|
|
-
|
|
|
- StateResulit(state_return);
|
|
|
- DebugL << "Deleting pipeline";
|
|
|
-
|
|
|
+ this->m_InferInfo = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 释放
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ void Inference::Destory(){
|
|
|
+ gst_element_set_state(this->pipeline, GST_STATE_NULL);
|
|
|
gst_object_unref(GST_OBJECT(this->pipeline));
|
|
|
g_source_remove(this->bus_watch_id);
|
|
|
g_main_loop_unref(this->loop);
|
|
|
g_mutex_clear (&eos_lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: Quit
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ void Inference::QuitLoop(){
|
|
|
+ g_main_loop_quit (this->loop);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 启动rtsp
|
|
|
+ * @param {guint} rtsp_port_num
|
|
|
+ * @param {guint} updsink_port_num
|
|
|
+ * @param {guint64} udp_buffer_size
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ gboolean Inference::start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num, guint64 udp_buffer_size)
|
|
|
+ {
|
|
|
+ GstRTSPMountPoints *mounts;
|
|
|
+ GstRTSPMediaFactory *factory;
|
|
|
+ char udpsrc_pipeline[512];
|
|
|
+ char port_num_Str[64] = { 0 };
|
|
|
+ if (udp_buffer_size == 0)
|
|
|
+ udp_buffer_size = 512 * 1024;
|
|
|
+ sprintf (udpsrc_pipeline,
|
|
|
+ "( udpsrc name=pay0 port=%d buffer-size=%lu caps=\"application/x-rtp, media=video, "
|
|
|
+ "clock-rate=90000, encoding-name=%s, payload=96 \" )",
|
|
|
+ updsink_port_num, udp_buffer_size, "H264");
|
|
|
+ sprintf (port_num_Str, "%d", rtsp_port_num);
|
|
|
+ g_mutex_lock (&server_cnt_lock);
|
|
|
+ server [server_count] = gst_rtsp_server_new ();
|
|
|
+ g_object_set (server [server_count], "service", port_num_Str, NULL);
|
|
|
+ mounts = gst_rtsp_server_get_mount_points (server [server_count]);
|
|
|
+ factory = gst_rtsp_media_factory_new ();
|
|
|
+ gst_rtsp_media_factory_set_launch (factory, udpsrc_pipeline);
|
|
|
+ gst_rtsp_mount_points_add_factory (mounts, "/live", factory);
|
|
|
+ g_object_unref (mounts);
|
|
|
+ gst_rtsp_server_attach (server [server_count], NULL);
|
|
|
+ server_count++;
|
|
|
+ g_mutex_unlock (&server_cnt_lock);
|
|
|
+ InfoL << "Play: rtsp://localhost:" << rtsp_port_num << "/live" << endl;
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: FloatToString
|
|
|
+ * @param {float} number
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+ std::string Inference::FloatToString(float number) {
|
|
|
+ char buffer[10];
|
|
|
+ snprintf(buffer, sizeof(buffer), "%.2f", number);
|
|
|
+ return std::string(buffer);
|
|
|
+ }
|
|
|
|
|
|
- this->m_InferInfo = NULL;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* @description: 获取Enable
|
|
|
* @return {*}
|
|
@@ -173,36 +167,33 @@ namespace gsd_ds{
|
|
|
*/
|
|
|
int32_t Inference::Init()
|
|
|
{
|
|
|
- m_recorder = recorder::CreateNew();
|
|
|
- // init
|
|
|
+ this->m_recorder = recorder::CreateNew();
|
|
|
this->loop = g_main_loop_new (NULL, FALSE);
|
|
|
-
|
|
|
- colors_ = GenerateColorsForCategories(80);
|
|
|
-
|
|
|
- // 创建管道
|
|
|
+ colors_ = osd::GenerateColorsForCategories(80);
|
|
|
+ // create pipeline
|
|
|
this->pipeline = gst_pipeline_new("gsd-pipeline");
|
|
|
|
|
|
- // 创建批处理器
|
|
|
+ // create streammux
|
|
|
this->streammux = gst_element_factory_make ("nvstreammux", "stream-muxer");
|
|
|
|
|
|
g_streammux = this->streammux;
|
|
|
|
|
|
- if(this->pipeline == NULL || this->streammux == NULL){
|
|
|
+ if(this->pipeline == nullptr || this->streammux == nullptr){
|
|
|
ErrorL << "One element could not be created. Exiting.";
|
|
|
return ERR;
|
|
|
}
|
|
|
-
|
|
|
- GstCaps *caps = NULL;
|
|
|
-
|
|
|
+
|
|
|
+ // gst_bin_add
|
|
|
gst_bin_add (GST_BIN (this->pipeline), streammux);
|
|
|
+
|
|
|
this->m_InferInfo = InferInfo::CreateNew();
|
|
|
g_InferInfo = this->m_InferInfo;
|
|
|
|
|
|
// 创建数据源
|
|
|
std::vector<DataSource>::iterator iter;
|
|
|
- g_num_sources = 0;
|
|
|
+ int num_sources = 0;
|
|
|
for(iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
|
|
|
- GstElement *source_bin = create_uridecode_bin (g_num_sources, (gchar*)((*iter).uri).c_str());
|
|
|
+ GstElement *source_bin = create_uridecode_bin (num_sources, (gchar*)((*iter).uri).c_str());
|
|
|
if (!source_bin) {
|
|
|
ErrorL << "Failed to create source bin. Exiting.";
|
|
|
return ERR;
|
|
@@ -210,7 +201,7 @@ namespace gsd_ds{
|
|
|
gst_bin_add(GST_BIN (this->pipeline), source_bin);
|
|
|
iter->source_bin = source_bin;
|
|
|
iter->Play = true;
|
|
|
- g_num_sources++;
|
|
|
+ num_sources++;
|
|
|
}
|
|
|
/* Use nvinfer to infer on batched frame. */
|
|
|
this->pgie = gst_element_factory_make("nvinfer", "primary-nvinference-engine");
|
|
@@ -233,30 +224,27 @@ namespace gsd_ds{
|
|
|
this->nvosd = gst_element_factory_make ("nvdsosd", "nv-onscreendisplay");
|
|
|
|
|
|
g_object_set (G_OBJECT (nvosd), "display-text", 1, NULL);
|
|
|
- g_object_set (G_OBJECT (nvosd), "display-clock", 1, NULL);
|
|
|
+ g_object_set (G_OBJECT (nvosd), "display-clock", 0, NULL);
|
|
|
g_object_set (G_OBJECT (nvosd), "display-bbox", 1, NULL);
|
|
|
g_object_set (G_OBJECT (nvosd), "display-mask", 1, NULL);
|
|
|
g_object_set (G_OBJECT (nvosd), "process-mode", 2, NULL);
|
|
|
|
|
|
this->caps_filter = gst_element_factory_make ("capsfilter", "capsfilter");
|
|
|
- caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
|
|
|
+ GstCaps *caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
|
|
|
this->encoder = gst_element_factory_make ("nvv4l2h264enc", "encoder");
|
|
|
-
|
|
|
- guint profile = 0;
|
|
|
- guint bitrate = 4000000;
|
|
|
- guint iframeinterval = 40;
|
|
|
-
|
|
|
+
|
|
|
this->codecparser = gst_element_factory_make ("h264parse", "h264-parser2");
|
|
|
this->rtppay = gst_element_factory_make ("rtph264pay", "rtppay");
|
|
|
this->sink = gst_element_factory_make ("udpsink", "udpsink");
|
|
|
|
|
|
g_object_set (G_OBJECT (caps_filter), "caps", caps, NULL);
|
|
|
- g_object_set (G_OBJECT (encoder), "profile", profile, NULL);
|
|
|
- g_object_set (G_OBJECT (encoder), "iframeinterval", iframeinterval, NULL);
|
|
|
- g_object_set (G_OBJECT (encoder), "bitrate", bitrate, NULL);
|
|
|
+ g_object_set (G_OBJECT (encoder), "profile", 0, NULL);
|
|
|
+ g_object_set (G_OBJECT (encoder), "iframeinterval", 50, NULL);
|
|
|
+ g_object_set (G_OBJECT (encoder), "bitrate", 4000000, NULL);
|
|
|
g_object_set (G_OBJECT (encoder), "preset-level", 1, NULL);
|
|
|
g_object_set (G_OBJECT (encoder), "insert-sps-pps", 1, NULL);
|
|
|
g_object_set (G_OBJECT (encoder), "bufapi-version", 1, NULL);
|
|
|
+
|
|
|
g_object_set (G_OBJECT (sink), "host", "224.224.255.255", "port",
|
|
|
5400, "async", FALSE, "sync", 0, NULL);
|
|
|
|
|
@@ -274,10 +262,8 @@ namespace gsd_ds{
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- g_object_set(G_OBJECT(streammux), "batch-size", g_num_sources, NULL);
|
|
|
-
|
|
|
+ g_object_set(G_OBJECT(streammux), "batch-size", num_sources, NULL);
|
|
|
g_object_set(G_OBJECT(streammux), "live-source", 1, NULL);
|
|
|
-
|
|
|
g_object_set (G_OBJECT (streammux), "width", MUXER_OUTPUT_WIDTH, "height",MUXER_OUTPUT_HEIGHT,
|
|
|
"batched-push-timeout", MUXER_BATCH_TIMEOUT_USEC, NULL);
|
|
|
|
|
@@ -288,9 +274,9 @@ namespace gsd_ds{
|
|
|
/* Override the batch-size set in the config file with the number of sources. */
|
|
|
g_object_get (G_OBJECT (this->pgie), "batch-size", &(this->pgie_batch_size), NULL);
|
|
|
|
|
|
- if ((int)this->pgie_batch_size != g_num_sources) {
|
|
|
- WarnL << "WARNING: Overriding infer-config batch-size:" << this->pgie_batch_size << "with number of sources ("<< g_num_sources << ")";
|
|
|
- g_object_set (G_OBJECT (this->pgie), "batch-size", g_num_sources, NULL);
|
|
|
+ if ((int)this->pgie_batch_size != num_sources) {
|
|
|
+ WarnL << "WARNING: Overriding infer-config batch-size:" << this->pgie_batch_size << "with number of sources ("<< num_sources << ")";
|
|
|
+ g_object_set (G_OBJECT (this->pgie), "batch-size", num_sources, NULL);
|
|
|
}
|
|
|
|
|
|
g_object_set (G_OBJECT (this->sink), "qos", 0, NULL);
|
|
@@ -301,24 +287,24 @@ namespace gsd_ds{
|
|
|
this->bus_watch_id = gst_bus_add_watch (this->bus, bus_call, this->loop);
|
|
|
gst_object_unref (this->bus);
|
|
|
|
|
|
- gst_bin_add_many (GST_BIN (this->pipeline), this->queue1, this->pgie, this->tiler, this->queue2, this->nvvidconv, this->nvosd, this->nvvidconv_postosd,this->queue3,this->caps_filter,this->queue4,this->encoder, this->rtppay, this->sink, NULL);
|
|
|
+ gst_bin_add_many (GST_BIN (this->pipeline),this->queue1, this->pgie,this->queue2, this->nvvidconv,this->tiler,this->nvosd,this->nvvidconv_postosd,this->caps_filter,this->queue4, this->encoder, this->queue3,this->rtppay, this->sink, NULL);
|
|
|
|
|
|
- if (!gst_element_link_many (streammux, this->queue1, this->pgie, this->tiler, this->queue2,this->nvvidconv, this->nvosd, this->nvvidconv_postosd,this->queue3,this->caps_filter,this->queue4, this->encoder, this->rtppay, this->sink, NULL)) {
|
|
|
+ if (!gst_element_link_many (streammux, this->queue1, this->pgie,this->queue2,this->nvvidconv, this->tiler,this->nvosd, this->nvvidconv_postosd,this->caps_filter,this->queue4, this->encoder, queue3,this->rtppay, this->sink, NULL)) {
|
|
|
ErrorL << "Elements could not be linked. Exiting.";
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- gboolean ret = TRUE;
|
|
|
- ret = start_rtsp_streaming (8554, 5400, 0);
|
|
|
-
|
|
|
+ start_rtsp_streaming (8554, 5400, 0);
|
|
|
+
|
|
|
this->DynamicAdjust();
|
|
|
|
|
|
this->tiler_sink_pad = gst_element_get_static_pad (this->nvvidconv, "src");
|
|
|
gst_pad_add_probe (this->tiler_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
|
|
|
tiler_sink_pad_buffer_probe, NULL, NULL);
|
|
|
gst_object_unref (this->tiler_sink_pad);
|
|
|
-
|
|
|
+
|
|
|
this->enable = true;
|
|
|
+
|
|
|
return OK;
|
|
|
}
|
|
|
|
|
@@ -332,17 +318,22 @@ namespace gsd_ds{
|
|
|
{
|
|
|
static int num = 0;
|
|
|
InfoL << "启动" << endl;
|
|
|
- pool.async([&](){
|
|
|
- if(num == 0){
|
|
|
- num++;
|
|
|
- this->RestartTask();
|
|
|
- // 不能去掉, 去掉会触发Deepstream内部句柄无法释放的Bug
|
|
|
- g_main_loop_run(this->loop);
|
|
|
- }else{
|
|
|
- this->RestartTask();
|
|
|
- }
|
|
|
- });
|
|
|
- pool.start();
|
|
|
+ gst_element_set_state(this->pipeline, GST_STATE_PLAYING);
|
|
|
+ g_main_loop_run(this->loop);
|
|
|
+ // if(m_pool == nullptr) return -1;
|
|
|
+ // m_pool->async([&](){
|
|
|
+ // if(num == 0){
|
|
|
+ // num++;
|
|
|
+ // this->RestartTask();
|
|
|
+ // // 不能去掉, 去掉会触发Deepstream内部句柄无法释放的Bug
|
|
|
+ // g_main_loop_run(this->loop);
|
|
|
+ // WarnL;
|
|
|
+
|
|
|
+ // }else{
|
|
|
+ // this->RestartTask();
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // m_pool->start();
|
|
|
return OK;
|
|
|
}
|
|
|
|
|
@@ -351,7 +342,8 @@ namespace gsd_ds{
|
|
|
* @param {int} num
|
|
|
* @return {*}
|
|
|
*/
|
|
|
- void Inference::SetBatch(int num){
|
|
|
+ void Inference::SetBatch(int num)
|
|
|
+ {
|
|
|
g_object_set(G_OBJECT(this->streammux), "batch-size", num, NULL);
|
|
|
g_object_set (G_OBJECT (this->pgie), "batch-size", num, NULL);
|
|
|
}
|
|
@@ -366,18 +358,13 @@ namespace gsd_ds{
|
|
|
{
|
|
|
GstStateChangeReturn state_return;
|
|
|
std::vector<DataSource>::iterator iter;
|
|
|
-
|
|
|
for (iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
|
|
|
if(iter->source_bin != NULL){
|
|
|
state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
|
|
|
StateResulit(state_return);
|
|
|
}
|
|
|
}
|
|
|
- state_return = gst_element_set_state(this->streammux, GST_STATE_NULL);
|
|
|
- StateResulit(state_return);
|
|
|
-
|
|
|
this->Play = false;
|
|
|
- NoticeCenter::Instance().emitEvent(NOTICE_RELEASE);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -388,33 +375,26 @@ namespace gsd_ds{
|
|
|
*/
|
|
|
int32_t Inference::RestartTask()
|
|
|
{
|
|
|
+ this->StopTask();
|
|
|
+
|
|
|
+ g_object_set (G_OBJECT (encoder), "profile", 0, NULL);
|
|
|
+ g_object_set (G_OBJECT (encoder), "iframeinterval", 40, NULL);
|
|
|
+ g_object_set (G_OBJECT (encoder), "bitrate", 4000000, NULL);
|
|
|
+ this->DynamicAdjust();
|
|
|
int num = 0;
|
|
|
- GstStateChangeReturn state_return;
|
|
|
std::vector<DataSource>::iterator iter;
|
|
|
for(iter=this->m_InferInfo->DataSources.begin(); iter!=this->m_InferInfo->DataSources.end();iter++){
|
|
|
if(iter->Play && iter->source_bin != NULL) num++;
|
|
|
}
|
|
|
- for (iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
|
|
|
- if(iter->source_bin != NULL){
|
|
|
- state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
|
|
|
- StateResulit(state_return);
|
|
|
- }
|
|
|
- }
|
|
|
- state_return = gst_element_set_state(this->streammux, GST_STATE_NULL);
|
|
|
- StateResulit(state_return);
|
|
|
-
|
|
|
if(num == 0){
|
|
|
DebugL << "没有数据源需要播放" << endl;
|
|
|
this->Play = false;
|
|
|
return ERR;
|
|
|
}
|
|
|
DebugL << "StartTask" << endl;
|
|
|
-
|
|
|
gst_element_set_state(this->pipeline, GST_STATE_PAUSED);
|
|
|
gst_element_set_state(this->pipeline, GST_STATE_PLAYING);
|
|
|
- m_frames.clear();
|
|
|
this->Play = true;
|
|
|
- InferNum++;
|
|
|
return OK;
|
|
|
}
|
|
|
|
|
@@ -496,12 +476,11 @@ namespace gsd_ds{
|
|
|
for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next)
|
|
|
{
|
|
|
obj_meta = (NvDsObjectMeta *) (l_obj->data);
|
|
|
- if (obj_meta->class_id == 14) {
|
|
|
+ if (obj_meta->class_id == 67) {
|
|
|
num++;
|
|
|
}
|
|
|
}
|
|
|
NoticeCenter::Instance().emitEvent(NOTICE_DEV, frame_meta->source_id, num);
|
|
|
-
|
|
|
if(src_data == nullptr) {
|
|
|
src_data = (char*) malloc(surface->surfaceList[frame_meta->batch_id].dataSize);
|
|
|
}
|
|
@@ -540,12 +519,12 @@ namespace gsd_ds{
|
|
|
// 编码数据
|
|
|
cv::resize(*frame, *frame, cv::Size(960, 540));
|
|
|
if(num == 0) {
|
|
|
- recorder::getPtr()->ConsumerData(g_InferInfo->DataSources[frame_meta->source_id].Pid, num, *frame);
|
|
|
+ recorder::getPtr()->ConsumerData(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id), num, *frame);
|
|
|
continue;
|
|
|
}
|
|
|
for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next){
|
|
|
obj_meta = (NvDsObjectMeta *) (l_obj->data);
|
|
|
- if (obj_meta->class_id == 14) {
|
|
|
+ if (obj_meta->class_id == 67) {
|
|
|
DsInferInfo data;
|
|
|
NvDsComp_BboxInfo boxInfo;
|
|
|
boxInfo = obj_meta->detector_bbox_info;
|
|
@@ -571,7 +550,7 @@ namespace gsd_ds{
|
|
|
cnStreamInferData->height = frame->rows;
|
|
|
for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next){
|
|
|
obj_meta = (NvDsObjectMeta *) (l_obj->data);
|
|
|
- if (obj_meta->class_id == 14) {
|
|
|
+ if (obj_meta->class_id == 67) {
|
|
|
NvDsComp_BboxInfo boxInfo;
|
|
|
boxInfo = obj_meta->detector_bbox_info;
|
|
|
NvBbox_Coords box_Coord;
|
|
@@ -588,15 +567,15 @@ namespace gsd_ds{
|
|
|
|
|
|
bottom_left.x = (box_Coord.left) / frame_width * frame->cols;
|
|
|
bottom_left.y = (box_Coord.top + box_Coord.height) / frame_height * frame->rows;
|
|
|
- DrawBox(*frame, top_left, bottom_right, colors_[obj_meta->class_id]);
|
|
|
+ osd::DrawBox(*frame, top_left, bottom_right, colors_[obj_meta->class_id]);
|
|
|
std::string text;
|
|
|
text = obj_meta->obj_label;
|
|
|
text = text + " " + FloatToString(obj_meta->confidence);
|
|
|
- if(num <= 5) DrawText(*frame, bottom_left, text, colors_[obj_meta->class_id]);
|
|
|
+ if(num <= 5) osd::DrawText(*frame, bottom_left, text, colors_[obj_meta->class_id]);
|
|
|
}
|
|
|
}
|
|
|
- recorder::getPtr()->ConsumerData(g_InferInfo->DataSources[frame_meta->source_id].Pid, num, *frame);
|
|
|
- cnStreamInferData->videoPath = recorder::getPtr()->GetFileName(g_InferInfo->DataSources[frame_meta->source_id].Pid);
|
|
|
+ recorder::getPtr()->ConsumerData(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id), num, *frame);
|
|
|
+ cnStreamInferData->videoPath = recorder::getPtr()->GetFileName(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id));
|
|
|
NoticeCenter::Instance().emitEvent(NOTICE_INFER, frame_meta->source_id, cnStreamInferData);
|
|
|
}
|
|
|
if(src_data != NULL) {
|
|
@@ -651,105 +630,6 @@ namespace gsd_ds{
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @description: 画框
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- void Inference::DrawBox(cv::Mat image, const cv::Point& top_left, const cv::Point& bottom_right,
|
|
|
- const cv::Scalar& color) {
|
|
|
- float w =bottom_right.x - top_left.x;
|
|
|
- float h =bottom_right.y - top_left.y;
|
|
|
- int wscale = w * .25f;
|
|
|
- int hscale = h * .25f;
|
|
|
- cv::Point top_right(bottom_right.x,top_left.y);
|
|
|
- cv::Point bottom_left(top_left.x,bottom_right.y);
|
|
|
- // --
|
|
|
- cv::line(image,top_left,cv::Point(top_left.x + wscale,top_left.y),color, CalcThickness(image.cols, 1));
|
|
|
- // |
|
|
|
- cv::line(image,top_left,cv::Point(top_left.x ,top_left.y + hscale),color, CalcThickness(image.cols, 1));
|
|
|
- // --
|
|
|
- cv::line(image,cv::Point(top_right.x - wscale,top_right.y),top_right,color, CalcThickness(image.cols, 1));
|
|
|
- // |
|
|
|
- cv::line(image,top_right,cv::Point(top_right.x,top_right.y + hscale),color, CalcThickness(image.cols, 1));
|
|
|
- //
|
|
|
- // __
|
|
|
- cv::line(image,bottom_left,cv::Point(bottom_left.x+wscale,bottom_left.y),color, CalcThickness(image.cols, 1));
|
|
|
- //
|
|
|
- //|
|
|
|
- cv::line(image,bottom_left,cv::Point(bottom_left.x,bottom_left.y - hscale),color, CalcThickness(image.cols, 1));
|
|
|
- //
|
|
|
- // |
|
|
|
- cv::line(image,bottom_right,cv::Point(bottom_right.x,bottom_right.y - hscale),color, CalcThickness(image.cols, 1));
|
|
|
-
|
|
|
- cv::line(image,bottom_right,cv::Point(bottom_right.x - wscale,bottom_right.y),color, CalcThickness(image.cols, 1));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @description:
|
|
|
- * @param {int} image_width
|
|
|
- * @param {float} thickness
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- int Inference::CalcThickness(int image_width, float thickness) {
|
|
|
- int result = thickness * image_width / 300;
|
|
|
- if (result <= 0) result = 1;
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @description: CalcScale
|
|
|
- * @param {int} image_width
|
|
|
- * @param {float} scale
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- double Inference::CalcScale(int image_width, float scale) {
|
|
|
- return scale * image_width / 1000;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @description: DrawText
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- void Inference::DrawText(cv::Mat image, const cv::Point& bottom_left, const std::string& text, const cv::Scalar& color,
|
|
|
- float scale, int* text_height) {
|
|
|
- double txt_scale = CalcScale(image.cols, 1) * scale;
|
|
|
- int txt_thickness = CalcThickness(image.cols, 1) * scale;
|
|
|
- int box_thickness = CalcThickness(image.cols, 1) * scale;
|
|
|
-
|
|
|
- int baseline = 0;
|
|
|
- int space_before = 0;
|
|
|
- cv::Size text_size;
|
|
|
- int label_height;
|
|
|
-
|
|
|
- text_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, txt_scale, txt_thickness, &baseline);
|
|
|
- space_before = 3 * txt_scale;
|
|
|
- text_size.width += space_before * 2;
|
|
|
-
|
|
|
- label_height = baseline + txt_thickness + text_size.height;
|
|
|
- int offset = (box_thickness == 1 ? 0 : - (box_thickness + 1) / 2);
|
|
|
- cv::Point label_top_left = bottom_left + cv::Point(offset, offset);
|
|
|
- cv::Point label_bottom_right = label_top_left + cv::Point(text_size.width + offset, label_height);
|
|
|
- // move up if the label is beyond the bottom of the image
|
|
|
- if (label_bottom_right.y > image.rows) {
|
|
|
- label_bottom_right.y -= label_height;
|
|
|
- label_top_left.y -= label_height;
|
|
|
- }
|
|
|
- // move left if the label is beyond the right side of the image
|
|
|
- if (label_bottom_right.x > image.cols) {
|
|
|
- label_bottom_right.x = image.cols;
|
|
|
- label_top_left.x = image.cols - text_size.width;
|
|
|
- }
|
|
|
- // draw text background
|
|
|
- cv::rectangle(image, label_top_left, label_bottom_right, color, -1);
|
|
|
- // draw text
|
|
|
- cv::Point text_left_bottom =
|
|
|
- label_top_left + cv::Point(space_before, label_height - baseline / 2 - txt_thickness / 2);
|
|
|
- cv::Scalar text_color = cv::Scalar(255, 255, 255) - color;
|
|
|
- char* str = const_cast<char*>(text.data());
|
|
|
- cv::putText(image, text, text_left_bottom, cv::FONT_HERSHEY_SIMPLEX, txt_scale, text_color, txt_thickness);
|
|
|
- if (text_height) *text_height = text_size.height + baseline;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* @description: 监听bus
|
|
|
* @param {GstBus *} bus Deepstream的bus
|
|
|
* @param {GstMessage *} msg 传递到bus中的msg
|
|
@@ -768,9 +648,9 @@ namespace gsd_ds{
|
|
|
gchar *debug;
|
|
|
GError *error;
|
|
|
gst_message_parse_warning (msg, &error, &debug);
|
|
|
- // WarnL << "WARNING from element " << GST_OBJECT_NAME (msg->src) << ": " << error->message;
|
|
|
+ WarnL << "WARNING from element " << GST_OBJECT_NAME (msg->src) << ": " << error->message;
|
|
|
g_free (debug);
|
|
|
- // WarnL << "Warning: " << error->message;
|
|
|
+ WarnL << "Warning: " << error->message;
|
|
|
g_error_free (error);
|
|
|
break;
|
|
|
}
|
|
@@ -815,16 +695,13 @@ namespace gsd_ds{
|
|
|
{
|
|
|
WarnL << "Decodebin child added: " << name;
|
|
|
if (g_strrstr (name, "decodebin") == name) {
|
|
|
-
|
|
|
g_signal_connect (G_OBJECT (object), "child-added",
|
|
|
G_CALLBACK (decodebin_child_added), user_data);
|
|
|
}
|
|
|
if (g_strrstr (name, "nvv4l2decoder") == name) {
|
|
|
#ifdef PLATFORM_TEGRA
|
|
|
g_object_set (object, "enable-max-performance", TRUE, NULL);
|
|
|
- //g_object_set (object, "bufapi-version", TRUE, NULL);
|
|
|
- g_object_set (object, "drop-frame-interval", 0, NULL);
|
|
|
- // g_object_set (object, "num-extra-surfaces", 2, NULL);
|
|
|
+ g_object_set (object, "drop-frame-interval", 2, NULL);
|
|
|
#else
|
|
|
g_object_set (object, "gpu-id", 0, NULL);
|
|
|
#endif
|
|
@@ -844,7 +721,6 @@ namespace gsd_ds{
|
|
|
GstPad *sinkpad = NULL;
|
|
|
GstState state;
|
|
|
gst_element_get_state(this->m_InferInfo->DataSources[source_id].source_bin,&state,NULL, GST_CLOCK_TIME_NONE);
|
|
|
- // DebugL << "state:" << state << endl;
|
|
|
WarnL << "stop_source ID:( " << source_id << " , " << this->m_InferInfo->DataSources[source_id].uri << ")" << endl;
|
|
|
if(state == GST_STATE_NULL){
|
|
|
gst_bin_remove (GST_BIN (this->pipeline), this->m_InferInfo->DataSources[source_id].source_bin);
|
|
@@ -854,10 +730,10 @@ namespace gsd_ds{
|
|
|
switch (state_return) {
|
|
|
case GST_STATE_CHANGE_SUCCESS:
|
|
|
InfoL << "STATE CHANGE SUCCESS";
|
|
|
- // g_snprintf (pad_name, 15, "sink_%u", source_id);
|
|
|
- // sinkpad = gst_element_get_static_pad (this->streammux, pad_name);
|
|
|
- // gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE));
|
|
|
- // gst_element_release_request_pad (this0>streammux, sinkpad);
|
|
|
+ g_snprintf (pad_name, 15, "sink_%u", source_id);
|
|
|
+ sinkpad = gst_element_get_static_pad (this->streammux, pad_name);
|
|
|
+ gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE));
|
|
|
+ gst_element_release_request_pad (this->streammux, sinkpad);
|
|
|
gst_bin_remove (GST_BIN (this->pipeline), this->m_InferInfo->DataSources[source_id].source_bin);
|
|
|
DebugL << "该source_bin移除成功" << endl;
|
|
|
break;
|
|
@@ -873,7 +749,7 @@ namespace gsd_ds{
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
g_mutex_unlock (&eos_lock);
|
|
|
}
|
|
|
|
|
@@ -890,7 +766,6 @@ namespace gsd_ds{
|
|
|
GstCaps *caps = gst_pad_query_caps (pad, NULL);
|
|
|
const GstStructure *str = gst_caps_get_structure (caps, 0);
|
|
|
const gchar *name = gst_structure_get_name (str);
|
|
|
-
|
|
|
WarnL << "decodebin new pad " << name;
|
|
|
if (!strncmp (name, "video", 5)) {
|
|
|
gint source_id = (*(gint *) data);
|
|
@@ -947,7 +822,7 @@ namespace gsd_ds{
|
|
|
{
|
|
|
g_mutex_lock (&eos_lock);
|
|
|
GstElement *source_bin;
|
|
|
-
|
|
|
+
|
|
|
source_bin = create_uridecode_bin (source_Id, (gchar *)uri.c_str());
|
|
|
if (!source_bin) {
|
|
|
ErrorL << "Failed to create source bin. Exiting.";
|
|
@@ -970,16 +845,6 @@ namespace gsd_ds{
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @description: 释放资源
|
|
|
- * @param {GstElement} *source_bin
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- void Inference::FreeElement(int source_Id,GstElement *source_bin)
|
|
|
- {
|
|
|
- // gst_object_unref(GST_OBJECT(source_bin));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* @description: 添加数据源
|
|
|
* @param {*}
|
|
|
* @return {*}
|
|
@@ -991,33 +856,19 @@ namespace gsd_ds{
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @description: 检查任务
|
|
|
- * @return {*}
|
|
|
- */
|
|
|
- void Inference::CheckTask()
|
|
|
- {
|
|
|
- GstState state;
|
|
|
- GstStateChangeReturn state_return;
|
|
|
- for (auto iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
|
|
|
- if(iter->source_bin != NULL){
|
|
|
- state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
|
|
|
- // StateResulit(state_return);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* @description: 动态调节
|
|
|
* @return {*}
|
|
|
*/
|
|
|
void Inference::DynamicAdjust(){
|
|
|
- int num = 0;
|
|
|
+ // int num = 0;
|
|
|
// std::vector<DataSource>::iterator iter;
|
|
|
// for(iter=this->m_InferInfo->DataSources.begin(); iter!=this->m_InferInfo->DataSources.end();iter++){
|
|
|
// if(iter->Play && iter->source_bin != NULL) num++;
|
|
|
// }
|
|
|
- // if(num <= 2) g_object_set (G_OBJECT (this->pgie), "interval", 1, NULL);
|
|
|
+ // if(num == 1) g_object_set (G_OBJECT (this->pgie), "interval", 0, NULL);
|
|
|
+ // else if(num <= 2) g_object_set (G_OBJECT (this->pgie), "interval", 1, NULL);
|
|
|
// else if(num > 2 && num <= 4) g_object_set (G_OBJECT (this->pgie), "interval", 2, NULL);
|
|
|
// else if(num > 4 && num <= 6) g_object_set (G_OBJECT (this->pgie), "interval", 3, NULL);
|
|
|
}
|
|
|
}
|
|
|
+
|