deepstream-no-osd.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. ############ Set properties for the Elements ############
  148. # Set Input Video files
  149. source1.set_property('location', INPUT_VIDEO_1)
  150. source2.set_property('location', INPUT_VIDEO_2)
  151. source3.set_property('location', INPUT_VIDEO_3)
  152. # Set Input Width , Height and Batch Size
  153. streammux.set_property('width', 1920)
  154. streammux.set_property('height', 1080)
  155. streammux.set_property('batch-size', 1)
  156. # Timeout in microseconds to wait after the first buffer is available
  157. # to push the batch even if a complete batch is not formed.
  158. streammux.set_property('batched-push-timeout', 4000000)
  159. # Set configuration file for nvinfer
  160. # Set Congifuration file for nvinfer
  161. pgie.set_property('config-file-path', "../source_code/N1/dstest4_pgie_config.txt")
  162. sgie1.set_property('config-file-path', "../source_code/N1/dstest4_sgie1_config.txt")
  163. sgie2.set_property('config-file-path', "../source_code/N1/dstest4_sgie2_config.txt")
  164. sgie3.set_property('config-file-path', "../source_code/N1/dstest4_sgie3_config.txt")
  165. #Set properties of tracker from tracker_config
  166. config = configparser.ConfigParser()
  167. config.read('../source_code/N1/dstest4_tracker_config.txt')
  168. config.sections()
  169. for key in config['tracker']:
  170. if key == 'tracker-width' :
  171. tracker_width = config.getint('tracker', key)
  172. tracker.set_property('tracker-width', tracker_width)
  173. if key == 'tracker-height' :
  174. tracker_height = config.getint('tracker', key)
  175. tracker.set_property('tracker-height', tracker_height)
  176. if key == 'gpu-id' :
  177. tracker_gpu_id = config.getint('tracker', key)
  178. tracker.set_property('gpu_id', tracker_gpu_id)
  179. if key == 'll-lib-file' :
  180. tracker_ll_lib_file = config.get('tracker', key)
  181. tracker.set_property('ll-lib-file', tracker_ll_lib_file)
  182. if key == 'll-config-file' :
  183. tracker_ll_config_file = config.get('tracker', key)
  184. tracker.set_property('ll-config-file', tracker_ll_config_file)
  185. if key == 'enable-batch-process' :
  186. tracker_enable_batch_process = config.getint('tracker', key)
  187. tracker.set_property('enable_batch_process', tracker_enable_batch_process)
  188. # Fake sink properties
  189. fakesink.set_property("sync", 0)
  190. fakesink.set_property("async", 0)
  191. ########## Add and Link ELements in the Pipeline ##########
  192. print("Adding elements to Pipeline \n")
  193. pipeline.add(source1)
  194. pipeline.add(h264parser1)
  195. pipeline.add(decoder1)
  196. pipeline.add(source2)
  197. pipeline.add(h264parser2)
  198. pipeline.add(decoder2)
  199. pipeline.add(source3)
  200. pipeline.add(h264parser3)
  201. pipeline.add(decoder3)
  202. pipeline.add(streammux)
  203. pipeline.add(pgie)
  204. pipeline.add(tracker)
  205. pipeline.add(sgie1)
  206. pipeline.add(sgie2)
  207. pipeline.add(sgie3)
  208. pipeline.add(fakesink)
  209. print("Linking elements in the Pipeline \n")
  210. source1.link(h264parser1)
  211. h264parser1.link(decoder1)
  212. ###### Create Sink pad and connect to decoder's source pad
  213. sinkpad1 = streammux.get_request_pad("sink_0")
  214. if not sinkpad1:
  215. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  216. srcpad1 = decoder1.get_static_pad("src")
  217. if not srcpad1:
  218. sys.stderr.write(" Unable to get source pad of decoder \n")
  219. srcpad1.link(sinkpad1)
  220. ######
  221. ###### Create Sink pad and connect to decoder's source pad
  222. source2.link(h264parser2)
  223. h264parser2.link(decoder2)
  224. sinkpad2 = streammux.get_request_pad("sink_1")
  225. if not sinkpad2:
  226. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  227. srcpad2 = decoder2.get_static_pad("src")
  228. if not srcpad2:
  229. sys.stderr.write(" Unable to get source pad of decoder \n")
  230. srcpad2.link(sinkpad2)
  231. ######
  232. ###### Create Sink pad and connect to decoder's source pad
  233. source3.link(h264parser3)
  234. h264parser3.link(decoder3)
  235. sinkpad3 = streammux.get_request_pad("sink_2")
  236. if not sinkpad2:
  237. sys.stderr.write(" Unable to get the sink pad of streammux \n")
  238. srcpad3 = decoder3.get_static_pad("src")
  239. if not srcpad3:
  240. sys.stderr.write(" Unable to get source pad of decoder \n")
  241. srcpad3.link(sinkpad3)
  242. ######
  243. streammux.link(pgie)
  244. pgie.link(tracker)
  245. tracker.link(sgie1)
  246. sgie1.link(sgie2)
  247. sgie2.link(sgie3)
  248. sgie3.link(fakesink)
  249. # create an event loop and feed gstreamer bus mesages to it
  250. loop = GLib.MainLoop()
  251. bus = pipeline.get_bus()
  252. bus.add_signal_watch()
  253. bus.connect ("message", bus_call, loop)
  254. print("Added and Linked elements to pipeline")
  255. src_pad=sgie3.get_static_pad("src")
  256. if not src_pad:
  257. sys.stderr.write(" Unable to get src pad \n")
  258. else:
  259. src_pad.add_probe(Gst.PadProbeType.BUFFER, src_pad_buffer_probe, 0)
  260. # List the sources
  261. print("Now playing...")
  262. print("Starting pipeline \n")
  263. # start play back and listed to events
  264. pipeline.set_state(Gst.State.PLAYING)
  265. start_time = time.time()
  266. try:
  267. loop.run()
  268. except:
  269. pass
  270. # cleanup
  271. print("Exiting app\n")
  272. pipeline.set_state(Gst.State.NULL)
  273. print("--- %s seconds ---" % (time.time() - start_time))