NVIDIA DeepStream SDK API Reference

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