NVIDIA DeepStream SDK API Reference

7.0 Release
deepstream_can_context_priv.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: LicenseRef-NvidiaProprietary
4  *
5  * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
6  * property and proprietary rights in and to this material, related
7  * documentation and any modifications thereto. Any use, reproduction,
8  * disclosure or distribution of this material and related documentation
9  * without an express license agreement from NVIDIA CORPORATION or
10  * its affiliates is strictly prohibited.
11  */
12 
13 #ifndef DS_APP_DEEPSTREAM_CAN_CONTEXT_PRIV_H
14 #define DS_APP_DEEPSTREAM_CAN_CONTEXT_PRIV_H
15 
17 #include <future>
18 
19 #include <cuda_runtime_api.h>
20 
21 #undef DS_CAN_FPS_INTERVAL
22 #define DS_CAN_FPS_INTERVAL 30
23 
25 public:
27  virtual ~Ds3dAppContext() { deinit(); }
28 
29  void setMainloop(GMainLoop* loop) { _mainLoop.reset(loop); }
30 
31  ErrCode init(const std::string& name)
32  {
33  int curDev = -1;
34  cudaGetDevice(&curDev);
35  struct cudaDeviceProp gpuProp;
36  cudaGetDeviceProperties(&gpuProp, curDev);
37  _isdGPU = (gpuProp.integrated ? false : true);
38 
41  _pipeline.reset(gst_pipeline_new(name.c_str()));
42  DS3D_FAILED_RETURN(pipeline(), ErrCode::kGst, "create pipeline: %s failed", name.c_str());
43  _pipeline.setName(name);
44  _bus.reset(gst_pipeline_get_bus(pipeline()));
45  DS3D_FAILED_RETURN(bus(), ErrCode::kGst, "get bus from pipeline: %s failed", name.c_str());
46  _busWatchId = gst_bus_add_watch(bus(), sBusCall, this);
47  return ErrCode::kGood;
48  }
49 
51  {
54  gst_bin_add(GST_BIN(pipeline()), ele.copy()), ErrCode::kGst, "add element failed");
55  _elementList.emplace_back(ele);
56  return *this;
57  }
58 
60  {
62  {
63  std::unique_lock<std::mutex> locker(mutex());
64  _eosReceived = false;
65  }
66  auto c = setPipelineState(GST_STATE_PLAYING);
67  return c;
68  }
69 
70  virtual ErrCode stop()
71  {
73  ErrCode c = setPipelineState(GST_STATE_NULL);
74  if (!isGood(c)) {
75  LOG_WARNING("set pipeline state to GST_STATE_NULL failed");
76  }
77  if (!isGood(c)) {
78  LOG_WARNING("set pipeline state to GST_STATE_NULL failed");
79  }
80  GstState end = GST_STATE_NULL;
81  c = getState(_pipeline.get(), &end, nullptr, 3000);
82  if (!isGood(c) || end != GST_STATE_NULL) {
83  LOG_WARNING("waiting for pipeline state to null failed, force to quit");
84  }
85  for (auto& each : _elementList) {
86  if (each) {
87  c = setState(each.get(), GST_STATE_NULL);
88  }
89  }
90  return c;
91  }
92 
93  /* timeout: milliseconds, 0 means never timeout */
94  bool isRunning(size_t timeout = 0)
95  {
96  std::unique_lock<std::mutex> locker(mutex());
97  if (!mainLoop() || !pipeline() || _mainStopped || _eosReceived) {
98  return false;
99  }
100  locker.unlock();
101 
102  GstState state = GST_STATE_NULL;
103  GstState pending = GST_STATE_NULL;
104  GstStateChangeReturn ret = gst_element_get_state(
105  GST_ELEMENT(pipeline()), &state, &pending,
106  (timeout ? timeout * 1000000 : GST_CLOCK_TIME_NONE));
107 
108  // basler camera has change state issue, try multi-times
109  uint32_t times = 1;
110  while (ret == GST_STATE_CHANGE_FAILURE && times++ < 3) {
111  ret = gst_element_get_state(GST_ELEMENT(pipeline()), &state, &pending, 0);
112  }
113  if (ret == GST_STATE_CHANGE_FAILURE) {
114  return false;
115  }
116  if (state == GST_STATE_PLAYING || pending == GST_STATE_PLAYING) {
117  return true;
118  }
119  return false;
120  }
121 
123  {
124  std::unique_lock<std::mutex> locker(mutex());
125  if (mainLoop()) {
126  g_main_loop_quit(mainLoop());
127  }
128  }
129 
131  {
132  std::unique_lock<std::mutex> locker(mutex());
133  if (mainLoop() && !_mainStopped && _mainLoopThread) {
134  _stoppedCond.wait_for(
135  locker, std::chrono::milliseconds(100), [this]() { return _mainStopped; });
136  }
137  _mainStopped = true;
138  if (_mainLoopThread) {
139  auto swapThread = std::move(_mainLoopThread);
140  _mainLoopThread.reset();
141  locker.unlock();
142  swapThread->join();
143  }
144  }
145 
146  void runMainLoop(std::function<void()> loopQuitCb)
147  {
148  std::unique_lock<std::mutex> locker(mutex());
149  if (mainLoop() && !_mainLoopThread) {
150  _mainStopped = false;
151  _mainLoopThread = std::make_unique<std::thread>([this, cb = std::move(loopQuitCb)]() {
152  g_main_loop_run(mainLoop());
153  cb();
154  std::unique_lock<std::mutex> locker(mutex());
155  _mainStopped = true;
156  _stoppedCond.notify_all();
157  });
159  }
160  }
161 
162  virtual void deinit()
163  {
164  if (bus()) {
165  gst_bus_remove_watch(bus());
166  }
167  _bus.reset();
168  _pipeline.reset();
169  _elementList.clear();
170  _mainLoop.reset();
171  }
172 
174  {
176  gst_element_send_event(GST_ELEMENT(pipeline()), gst_event_new_eos()), ErrCode::kGst,
177  "send EOS failed");
178  return ErrCode::kGood;
179  }
180 
181  GstPipeline* pipeline() const { return GST_PIPELINE_CAST(_pipeline.get()); }
182  GstBus* bus() const { return _bus.get(); }
183  GMainLoop* mainLoop() const { return _mainLoop.get(); }
184 
185 private:
186  // no need to free msg
187  virtual bool busCall(GstMessage* msg) = 0;
188 
189 protected:
190  ErrCode setPipelineState(GstState state)
191  {
193  return setState(_pipeline.get(), state);
194  }
195 
196  ErrCode setState(GstElement* ele, GstState state)
197  {
198  DS_ASSERT(ele);
199  GstStateChangeReturn ret = gst_element_set_state(ele, state);
201  ret != GST_STATE_CHANGE_FAILURE, ErrCode::kGst, "element set state: %d failed", state);
202  return ErrCode::kGood;
203  }
204  /* get element states. timeout in milliseconds.
205  */
207  GstElement* ele, GstState* state, GstState* pending = nullptr, size_t timeout = 0)
208  {
209  DS_ASSERT(ele);
210  GstStateChangeReturn ret = gst_element_get_state(
211  ele, state, pending, (timeout ? timeout * 1000000 : GST_CLOCK_TIME_NONE));
212  switch (ret) {
213  case GST_STATE_CHANGE_FAILURE:
214  return ErrCode::kGst;
215  case GST_STATE_CHANGE_SUCCESS:
216  case GST_STATE_CHANGE_NO_PREROLL:
217  return ErrCode::kGood;
218  default:
219  return ErrCode::kUnknown;
220  }
221  return ErrCode::kGood;
222  }
223 
224  static gboolean sBusCall(GstBus* bus, GstMessage* msg, gpointer data)
225  {
226  Ds3dAppContext* ctx = static_cast<Ds3dAppContext*>(data);
227  DS_ASSERT(ctx->bus() == bus);
228  return ctx->busCall(msg);
229  }
230 
231  std::mutex& mutex() const { return _streamMutex; }
232 
233  // members
236  uint32_t _busWatchId = 0;
237  std::vector<gst::ElePtr> _elementList;
238  ds3d::UniqPtr<GMainLoop> _mainLoop{nullptr, g_main_loop_unref};
239  bool _eosAutoQuit = false;
240  std::unique_ptr<std::thread> _mainLoopThread;
241  bool _mainStopped = false;
242  bool _eosReceived = false;
243  mutable std::mutex _streamMutex;
244  std::condition_variable _stoppedCond;
245  bool _isdGPU = true;
247 };
248 
249 class CameraCanApp : public Ds3dAppContext {
250 public:
251  CameraCanApp() = default;
253 
254  void setConfig(const NvDsCanContextConfig& config) { _config = config; }
255  const NvDsCanContextConfig& config() const { return _config; }
256 
258 
259  ErrCode stop() override;
260 
261  void deinit() override
262  {
264  _src.reset();
265  _appsrcFrameIdx = 0;
266  }
267 
269  const NvDsCanContextFrame* frame, std::function<void(GstBuffer*)> callback);
270 
271  NvDsCanSrcType srcType() const { return _config.srcType; }
272 
273  static GstPadProbeReturn lastSinkBufferProbe(
274  GstPad* pad, GstPadProbeInfo* info, gpointer udata);
275  static GstPadProbeReturn processedBufferProbe(
276  GstPad* pad, GstPadProbeInfo* info, gpointer udata);
277 
278 private:
279  bool busCall(GstMessage* msg) final;
280  void outputBuffer(GstBuffer* buf);
281  void visualMetaUpdate(GstBuffer* buf);
282  void printOutputResult(GstBuffer* buf);
283 
284  gst::ElePtr createAppSrc(const NvDsCanFrameInfo& info);
285  gst::ElePtr createSourceBin(const std::string& uri);
286  gst::ElePtr createCameraSrc(const NvDsCanCameraInfo& conf);
287  gst::ElePtr createSink();
288 
289 private:
290  NvDsCanContextConfig _config;
291  gst::ElePtr _src;
292  std::function<void(GstBuffer* buf)> _outputCallback = nullptr;
293  uint64_t _appsrcFrameIdx = 0;
295  uint64_t _bufId = 0;
296 };
297 
298 #endif // DS_APP_DEEPSTREAM_CAN_CONTEXT_PRIV_H
ds3d::isGood
bool isGood(ErrCode c)
Definition: func_utils.h:28
Ds3dAppContext::quitMainLoop
void quitMainLoop()
Definition: deepstream_can_context_priv.hpp:122
Ds3dAppContext::_mainLoop
ds3d::UniqPtr< GMainLoop > _mainLoop
Definition: deepstream_can_context_priv.hpp:238
Ds3dAppContext::mainLoop
GMainLoop * mainLoop() const
Definition: deepstream_can_context_priv.hpp:183
CameraCanApp::setConfig
void setConfig(const NvDsCanContextConfig &config)
Definition: deepstream_can_context_priv.hpp:254
CameraCanApp::config
const NvDsCanContextConfig & config() const
Definition: deepstream_can_context_priv.hpp:255
Ds3dAppContext::bus
GstBus * bus() const
Definition: deepstream_can_context_priv.hpp:182
CameraCanApp::~CameraCanApp
~CameraCanApp()
Definition: deepstream_can_context_priv.hpp:252
NvDsCanContextFrame
Definition: deepstream_can_context.hpp:42
Ds3dAppContext
Definition: deepstream_can_context_priv.hpp:24
ds3d::UniqPtr
std::unique_ptr< T, std::function< void(T *)> > UniqPtr
Definition: obj.hpp:31
DS_ASSERT
#define DS_ASSERT(...)
Definition: defines.h:31
Ds3dAppContext::setState
ErrCode setState(GstElement *ele, GstState state)
Definition: deepstream_can_context_priv.hpp:196
Ds3dAppContext::runMainLoop
void runMainLoop(std::function< void()> loopQuitCb)
Definition: deepstream_can_context_priv.hpp:146
DS_CAN_FPS_INTERVAL
#define DS_CAN_FPS_INTERVAL
Definition: deepstream_can_context_priv.hpp:22
LOG_WARNING
#define LOG_WARNING
Definition: logging.h:17
Ds3dAppContext::mutex
std::mutex & mutex() const
Definition: deepstream_can_context_priv.hpp:231
Ds3dAppContext::_elementList
std::vector< gst::ElePtr > _elementList
Definition: deepstream_can_context_priv.hpp:237
ds3d::gst::GstPtr
Definition: nvds3d_gst_ptr.h:54
NvDsCanFrameInfo
Definition: deepstream_can_context.hpp:60
Ds3dAppContext::waitLoopQuit
void waitLoopQuit()
Definition: deepstream_can_context_priv.hpp:130
Ds3dAppContext::~Ds3dAppContext
virtual ~Ds3dAppContext()
Definition: deepstream_can_context_priv.hpp:27
Ds3dAppContext::_eosReceived
bool _eosReceived
Definition: deepstream_can_context_priv.hpp:242
Ds3dAppContext::_isdGPU
bool _isdGPU
Definition: deepstream_can_context_priv.hpp:245
ds3d::gst::ElePtr
Definition: nvds3d_gst_ptr.h:150
Ds3dAppContext::play
ErrCode play()
Definition: deepstream_can_context_priv.hpp:59
CameraCanApp::processFrame
ErrCode processFrame(const NvDsCanContextFrame *frame, std::function< void(GstBuffer *)> callback)
Ds3dAppContext::isRunning
bool isRunning(size_t timeout=0)
Definition: deepstream_can_context_priv.hpp:94
Ds3dAppContext::_pipeline
gst::ElePtr _pipeline
Definition: deepstream_can_context_priv.hpp:234
Ds3dAppContext::add
Ds3dAppContext & add(const gst::ElePtr &ele)
Definition: deepstream_can_context_priv.hpp:50
ds3d::ErrCode
ErrCode
Definition: common.h:43
ds3d::gst::GstPtr::setName
void setName(const std::string &name)
Definition: nvds3d_gst_ptr.h:68
Ds3dAppContext::_bus
gst::BusPtr _bus
Definition: deepstream_can_context_priv.hpp:235
deepstream_can_context.hpp
Ds3dAppContext::_stoppedCond
std::condition_variable _stoppedCond
Definition: deepstream_can_context_priv.hpp:244
CameraCanApp::deinit
void deinit() override
Definition: deepstream_can_context_priv.hpp:261
ds3d::gst::GstPtr::copy
GstObjT * copy() const
Definition: nvds3d_gst_ptr.h:98
Ds3dAppContext::_mainStopped
bool _mainStopped
Definition: deepstream_can_context_priv.hpp:241
ds3d::gst::GstPtr::get
GstObjT * get() const
Definition: nvds3d_gst_ptr.h:110
Ds3dAppContext::deinit
virtual void deinit()
Definition: deepstream_can_context_priv.hpp:162
CameraCanApp::buildPipeline
ErrCode buildPipeline()
NvDsCanCameraInfo
Definition: deepstream_can_context.hpp:66
CameraCanApp::srcType
NvDsCanSrcType srcType() const
Definition: deepstream_can_context_priv.hpp:271
CameraCanApp::stop
ErrCode stop() override
Ds3dAppContext::_eosAutoQuit
bool _eosAutoQuit
Definition: deepstream_can_context_priv.hpp:239
DS3D_THROW_ERROR
#define DS3D_THROW_ERROR(statement, code, msg)
Definition: defines.h:78
CameraCanApp::processedBufferProbe
static GstPadProbeReturn processedBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer udata)
Ds3dAppContext::sendEOS
ErrCode sendEOS()
Definition: deepstream_can_context_priv.hpp:173
ds3d::profiling::FpsCalculation
Definition: profiling.hpp:23
CameraCanApp
Definition: deepstream_can_context_priv.hpp:249
NvDsCanSrcType
NvDsCanSrcType
Definition: deepstream_can_context.hpp:53
Ds3dAppContext::pipeline
GstPipeline * pipeline() const
Definition: deepstream_can_context_priv.hpp:181
Ds3dAppContext::sBusCall
static gboolean sBusCall(GstBus *bus, GstMessage *msg, gpointer data)
Definition: deepstream_can_context_priv.hpp:224
CameraCanApp::lastSinkBufferProbe
static GstPadProbeReturn lastSinkBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer udata)
GstBuffer
struct _GstBuffer GstBuffer
Definition: idatatype.h:19
Ds3dAppContext::setPipelineState
ErrCode setPipelineState(GstState state)
Definition: deepstream_can_context_priv.hpp:190
Ds3dAppContext::_mainLoopThread
std::unique_ptr< std::thread > _mainLoopThread
Definition: deepstream_can_context_priv.hpp:240
DS3D_FAILED_RETURN
#define DS3D_FAILED_RETURN(condition, ret, fmt,...)
Definition: defines.h:64
NvDsCanContextConfig
Definition: deepstream_can_context.hpp:74
Ds3dAppContext::getState
ErrCode getState(GstElement *ele, GstState *state, GstState *pending=nullptr, size_t timeout=0)
Definition: deepstream_can_context_priv.hpp:206
CameraCanApp::CameraCanApp
CameraCanApp()=default
Ds3dAppContext::DS3D_DISABLE_CLASS_COPY
DS3D_DISABLE_CLASS_COPY(Ds3dAppContext)
NvDsCanContextConfig::srcType
NvDsCanSrcType srcType
Definition: deepstream_can_context.hpp:75
Ds3dAppContext::Ds3dAppContext
Ds3dAppContext()
Definition: deepstream_can_context_priv.hpp:26
ds3d::gst::GstPtr::reset
void reset(GstObjT *obj=nullptr, bool takeOwner=true)
Definition: nvds3d_gst_ptr.h:89
Ds3dAppContext::_streamMutex
std::mutex _streamMutex
Definition: deepstream_can_context_priv.hpp:243
Ds3dAppContext::_busWatchId
uint32_t _busWatchId
Definition: deepstream_can_context_priv.hpp:236
Ds3dAppContext::stop
virtual ErrCode stop()
Definition: deepstream_can_context_priv.hpp:70
Ds3dAppContext::init
ErrCode init(const std::string &name)
Definition: deepstream_can_context_priv.hpp:31
Ds3dAppContext::setMainloop
void setMainloop(GMainLoop *loop)
Definition: deepstream_can_context_priv.hpp:29