deepstream-no-osd-queue-prof.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. # Import required libraries
  2. import sys
  3. sys.path.append('../')
  4. sys.path.append('../source_code')
  5. import gi
  6. import configparser
  7. gi.require_version('Gst', '1.0')
  8. from gi.repository import GObject, Gst
  9. from gi.repository import GLib
  10. from ctypes import *
  11. import time
  12. import sys
  13. import math
  14. import platform
  15. from common.bus_call import bus_call
  16. from common.FPS import GETFPS
  17. import pyds
  18. PGIE_CLASS_ID_VEHICLE = 0
  19. PGIE_CLASS_ID_BICYCLE = 1
  20. PGIE_CLASS_ID_PERSON = 2
  21. PGIE_CLASS_ID_ROADSIGN = 3
  22. MUXER_OUTPUT_WIDTH=1920
  23. MUXER_OUTPUT_HEIGHT=1080
  24. TILED_OUTPUT_WIDTH=1920
  25. TILED_OUTPUT_HEIGHT=1080
  26. OSD_PROCESS_MODE= 0
  27. OSD_DISPLAY_TEXT= 0
  28. pgie_classes_str= ["Vehicle", "TwoWheeler", "Person","RoadSign"]
  29. ################ Three Stream Pipeline ###########
  30. # Define Input and output Stream information
  31. num_sources = 3
  32. INPUT_VIDEO_1 = '/opt/nvidia/deepstream/deepstream-5.0/samples/streams/sample_720p.h264'
  33. INPUT_VIDEO_2 = '/opt/nvidia/deepstream/deepstream-5.0/samples/streams/sample_720p.h264'
  34. INPUT_VIDEO_3 = '/opt/nvidia/deepstream/deepstream-5.0/samples/streams/sample_720p.h264'
  35. ## Make Element or Print Error and any other detail
  36. def make_elm_or_print_err(factoryname, name, printedname, detail=""):
  37. print("Creating", printedname)
  38. elm = Gst.ElementFactory.make(factoryname, name)
  39. if not elm:
  40. sys.stderr.write("Unable to create " + printedname + " \n")
  41. if detail:
  42. sys.stderr.write(detail)
  43. return elm
  44. # src_pad_buffer_probe
  45. def src_pad_buffer_probe(pad,info,u_data):
  46. #Intiallizing object counter with 0.
  47. obj_counter = {
  48. PGIE_CLASS_ID_VEHICLE:0,
  49. PGIE_CLASS_ID_PERSON:0,
  50. PGIE_CLASS_ID_BICYCLE:0,
  51. PGIE_CLASS_ID_ROADSIGN:0
  52. }
  53. # Set frame_number & rectangles to draw as 0
  54. frame_number=0
  55. num_rects=0
  56. gst_buffer = info.get_buffer()
  57. if not gst_buffer:
  58. print("Unable to get GstBuffer ")
  59. return
  60. # Retrieve batch metadata from the gst_buffer
  61. # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the
  62. # C address of gst_buffer as input, which is obtained with hash(gst_buffer)
  63. batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
  64. l_frame = batch_meta.frame_meta_list
  65. while l_frame is not None:
  66. try:
  67. # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta
  68. frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
  69. except StopIteration:
  70. break
  71. # Get frame number , number of rectables to draw and object metadata
  72. frame_number=frame_meta.frame_num
  73. num_rects = frame_meta.num_obj_meta
  74. l_obj=frame_meta.obj_meta_list
  75. while l_obj is not None:
  76. try:
  77. # Casting l_obj.data to pyds.NvDsObjectMeta
  78. obj_meta=pyds.NvDsObjectMeta.cast(l_obj.data)
  79. except StopIteration:
  80. break
  81. # Increment Object class by 1
  82. obj_counter[obj_meta.class_id] += 1
  83. try:
  84. l_obj=l_obj.next
  85. except StopIteration:
  86. break
  87. print("Frame Number={} Number of Objects={} Vehicle_count={} Person_count={}".format(frame_number, num_rects, obj_counter[PGIE_CLASS_ID_VEHICLE], obj_counter[PGIE_CLASS_ID_PERSON]))
  88. # FPS Probe
  89. fps_streams_new["stream{0}".format(frame_meta.pad_index)].get_fps()
  90. try:
  91. l_frame=l_frame.next
  92. except StopIteration:
  93. break
  94. return Gst.PadProbeReturn.OK
  95. # Define variables to be used later
  96. fps_streams_new={}
  97. # Initialise FPS
  98. for i in range(0,num_sources):
  99. fps_streams_new["stream{0}".format(i)]=GETFPS(i)
  100. # Standard GStreamer initialization
  101. Gst.init(None)
  102. # Create gstreamer elements */
  103. # Create Pipeline element that will form a connection of other elements
  104. print("Creating Pipeline \n ")
  105. pipeline = Gst.Pipeline()
  106. if not pipeline:
  107. sys.stderr.write(" Unable to create Pipeline \n")
  108. ########### Create Elements required for the Pipeline ###########
  109. ######### Defining Stream 1
  110. # Source element for reading from the file
  111. source1 = make_elm_or_print_err("filesrc", "file-source-1",'file-source-1')
  112. # Since the data format in the input file is elementary h264 stream,we need a h264parser
  113. h264parser1 = make_elm_or_print_err("h264parse", "h264-parser-1","h264-parser-1")
  114. # Use nvdec_h264 for hardware accelerated decode on GPU
  115. decoder1 = make_elm_or_print_err("nvv4l2decoder", "nvv4l2-decoder-1","nvv4l2-decoder-1")
  116. ##########
  117. ########## Defining Stream 2
  118. # Source element for reading from the file
  119. source2 = make_elm_or_print_err("filesrc", "file-source-2","file-source-2")
  120. # Since the data format in the input file is elementary h264 stream, we need a h264parser
  121. h264parser2 = make_elm_or_print_err("h264parse", "h264-parser-2", "h264-parser-2")
  122. # Use nvdec_h264 for hardware accelerated decode on GPU
  123. decoder2 = make_elm_or_print_err("nvv4l2decoder", "nvv4l2-decoder-2","nvv4l2-decoder-2")
  124. ###########
  125. ########## Defining Stream 3
  126. # Source element for reading from the file
  127. source3 = make_elm_or_print_err("filesrc", "file-source-3","file-source-3")
  128. # Since the data format in the input file is elementary h264 stream, we need a h264parser
  129. h264parser3 = make_elm_or_print_err("h264parse", "h264-parser-3", "h264-parser-3")
  130. # Use nvdec_h264 for hardware accelerated decode on GPU
  131. decoder3 = make_elm_or_print_err("nvv4l2decoder", "nvv4l2-decoder-3","nvv4l2-decoder-3")
  132. ###########
  133. # Create nvstreammux instance to form batches from one or more sources.
  134. streammux = make_elm_or_print_err("nvstreammux", "Stream-muxer","Stream-muxer")
  135. # Use nvinfer to run inferencing on decoder's output, behaviour of inferencing is set through config file
  136. pgie = make_elm_or_print_err("nvinfer", "primary-inference" ,"pgie")
  137. # Use nvtracker to give objects unique-ids
  138. tracker = make_elm_or_print_err("nvtracker", "tracker",'tracker')
  139. # Seconday inference for Finding Car Color
  140. sgie1 = make_elm_or_print_err("nvinfer", "secondary1-nvinference-engine",'sgie1')
  141. # Seconday inference for Finding Car Make
  142. sgie2 = make_elm_or_print_err("nvinfer", "secondary2-nvinference-engine",'sgie2')
  143. # # Seconday inference for Finding Car Type
  144. sgie3 = make_elm_or_print_err("nvinfer", "secondary3-nvinference-engine",'sgie3')
  145. # Create Sink for storing the output
  146. fakesink = make_elm_or_print_err("fakesink", "fakesink", "Sink")
  147. # Queues to enable buffering
  148. queue1=make_elm_or_print_err("queue","queue1","queue1")
  149. queue2=make_elm_or_print_err("queue","queue2","queue2")
  150. queue3=make_elm_or_print_err("queue","queue3","queue3")
  151. queue4=make_elm_or_print_err("queue","queue4","queue4")
  152. queue5=make_elm_or_print_err("queue","queue5","queue5")
  153. queue6=make_elm_or_print_err("queue","queue6","queue6")
  154. ############ Set properties for the Elements ############
  155. # Set Input Video files
  156. source1.set_property('location', INPUT_VIDEO_1)
  157. source2.set_property('location', INPUT_VIDEO_2)
  158. source3.set_property('location', INPUT_VIDEO_3)
  159. # Set Input Width , Height and Batch Size
  160. streammux.set_property('width', 1920)
  161. streammux.set_property('height', 1080)
  162. streammux.set_property('batch-size', 1)
  163. # Timeout in microseconds to wait after the first buffer is available
  164. # to push the batch even if a complete batch is not formed.
  165. streammux.set_property('batched-push-timeout', 4000000)
  166. # Set configuration file for nvinfer
  167. # Set Congifuration file for nvinfer
  168. pgie.set_property('config-file-path', "../source_code/N1/dstest4_pgie_config.txt")
  169. sgie1.set_property('config-file-path', "../source_code/N1/dstest4_sgie1_config.txt")
  170. sgie2.set_property('config-file-path', "../source_code/N1/dstest4_sgie2_config.txt")
  171. sgie3.set_property('config-file-path', "../source_code/N1/dstest4_sgie3_config.txt")
  172. #Set properties of tracker from tracker_config
  173. config = configparser.ConfigParser()
  174. config.read('../source_code/N1/dstest4_tracker_config.txt')
  175. config.sections()
  176. for key in config['tracker']:
  177. if key == 'tracker-width' :
  178. tracker_width = config.getint('tracker', key)
  179. tracker.set_property('tracker-width', tracker_width)
  180. if key == 'tracker-height' :
  181. tracker_height = config.getint('tracker', key)
  182. tracker.set_property('tracker-height', tracker_height)
  183. if key == 'gpu-id' :
  184. tracker_gpu_id = config.getint('tracker', key)
  185. tracker.set_property('gpu_id', tracker_gpu_id)
  186. if key == 'll-lib-file' :
  187. tracker_ll_lib_file = config.get('tracker', key)
  188. tracker.set_property('ll-lib-file', tracker_ll_lib_file)
  189. if key == 'll-config-file' :
  190. tracker_ll_config_file = config.get('tracker', key)
  191. tracker.set_property('ll-config-file', tracker_ll_config_file)
  192. if key == 'enable-batch-process' :
  193. tracker_enable_batch_process = config.getint('tracker', key)
  194. tracker.set_property('enable_batch_process', tracker_enable_batch_process)
  195. # Fake sink properties
  196. fakesink.set_property("sync", 0)
  197. fakesink.set_property("async", 0)
  198. ########## Add and Link ELements in the Pipeline ##########
  199. print("Adding elements to Pipeline \n")
  200. pipeline.add(source1)
  201. pipeline.add(h264parser1)
  202. pipeline.add(decoder1)
  203. pipeline.add(source2)
  204. pipeline.add(h264parser2)
  205. pipeline.add(decoder2)
  206. pipeline.add(source3)
  207. pipeline.add(h264parser3)
  208. pipeline.add(decoder3)
  209. pipeline.add(streammux)
  210. pipeline.add(queue1)
  211. pipeline.add(pgie)
  212. pipeline.add(queue2)
  213. pipeline.add(tracker)
  214. pipeline.add(queue3)
  215. pipeline.add(sgie1)
  216. pipeline.add(queue4)
  217. pipeline.add(sgie2)
  218. pipeline.add(queue5)
  219. pipeline.add(sgie3)
  220. pipeline.add(queue6)
  221. pipeline.add(fakesink)
  222. print("Linking elements in the Pipeline \n")
  223. source1.link(h264parser1)
  224. h264parser1.link(decoder1)
  225. ###### Create Sink pad and connect to decoder's source pad
  226. sinkpad1 = streammux.get_request_pad("sink_0")
  227. if not sinkpad1:
  228. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  229. srcpad1 = decoder1.get_static_pad("src")
  230. if not srcpad1:
  231. sys.stderr.write(" Unable to get source pad of decoder \n")
  232. srcpad1.link(sinkpad1)
  233. ######
  234. ###### Create Sink pad and connect to decoder's source pad
  235. source2.link(h264parser2)
  236. h264parser2.link(decoder2)
  237. sinkpad2 = streammux.get_request_pad("sink_1")
  238. if not sinkpad2:
  239. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  240. srcpad2 = decoder2.get_static_pad("src")
  241. if not srcpad2:
  242. sys.stderr.write(" Unable to get source pad of decoder \n")
  243. srcpad2.link(sinkpad2)
  244. ######
  245. ###### Create Sink pad and connect to decoder's source pad
  246. source3.link(h264parser3)
  247. h264parser3.link(decoder3)
  248. sinkpad3 = streammux.get_request_pad("sink_2")
  249. if not sinkpad2:
  250. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  251. srcpad3 = decoder3.get_static_pad("src")
  252. if not srcpad3:
  253. sys.stderr.write(" Unable to get source pad of decoder \n")
  254. srcpad3.link(sinkpad3)
  255. ######
  256. streammux.link(queue1)
  257. queue1.link(pgie)
  258. pgie.link(queue2)
  259. queue2.link(tracker)
  260. tracker.link(queue3)
  261. queue3.link(sgie1)
  262. sgie1.link(queue4)
  263. queue4.link(sgie2)
  264. sgie2.link(queue5)
  265. queue5.link(sgie3)
  266. sgie3.link(fakesink)
  267. # queue6.link(fakesink)
  268. # create an event loop and feed gstreamer bus mesages to it
  269. loop = GLib.MainLoop()
  270. bus = pipeline.get_bus()
  271. bus.add_signal_watch()
  272. bus.connect ("message", bus_call, loop)
  273. print("Added and Linked elements to pipeline")
  274. src_pad=sgie3.get_static_pad("src")
  275. if not src_pad:
  276. sys.stderr.write(" Unable to get src pad \n")
  277. else:
  278. src_pad.add_probe(Gst.PadProbeType.BUFFER, src_pad_buffer_probe, 0)
  279. # List the sources
  280. print("Now playing...")
  281. print("Starting pipeline \n")
  282. # start play back and listed to events
  283. pipeline.set_state(Gst.State.PLAYING)
  284. start_time = time.time()
  285. try:
  286. loop.run()
  287. except:
  288. pass
  289. # cleanup
  290. print("Exiting app\n")
  291. pipeline.set_state(Gst.State.NULL)
  292. print("--- %s seconds ---" % (time.time() - start_time))