@@ -28,43 +28,40 @@ def __init__(self):
28
28
"h264parse ! "
29
29
"mp4mux ! "
30
30
"filesink "
31
- " location={VIDEO_OUTPUT_PATH} "
31
+ " location={VIDEO_OUTPUT_PATH} async=false "
32
32
)
33
33
34
+
34
35
self ._recording_stream = (
35
36
"filesrc "
36
37
" location={VIDEO_PATH} ! "
37
38
"qtdemux ! "
38
39
"h264parse ! "
39
40
"tee name=t{id} ! "
40
- "queue2 max-size-bytes=0 max-size-time=0 ! "
41
+ "queue2 ! "
41
42
"mp4mux ! "
42
43
"filesink "
43
44
" location=/tmp/stream{id}.mp4 "
44
45
"t{id}. ! "
45
- "queue2 max-size-bytes=0 max-size-time=0 ! "
46
+ "queue2 ! "
46
47
"{decoder} ! "
47
- "gvafpscounter starting-frame=1000 ! "
48
- "queue2 max-size-bytes=0 max-size-time=0 ! "
49
- "{postprocessing} ! "
50
- "video/x-raw,width=640,height=360 ! "
51
- "comp.sink_{id} "
48
+ "gvafpscounter starting-frame=500 ! "
52
49
)
53
50
54
- self ._inference_stream = (
51
+ self ._inference_stream_decode_detect_track = (
55
52
"filesrc "
56
53
" location={VIDEO_PATH} ! "
57
54
"qtdemux ! "
58
55
"h264parse ! "
59
56
"tee name=t{id} ! "
60
- "queue2 max-size-bytes=0 max-size-time=0 ! "
57
+ "queue2 ! "
61
58
"mp4mux ! "
62
59
"filesink "
63
60
" location=/tmp/stream{id}.mp4 "
64
61
"t{id}. ! "
65
- "queue2 max-size-bytes=0 max-size-time=0 ! "
62
+ "queue2 ! "
66
63
"{decoder} ! "
67
- "gvafpscounter starting-frame=1000 ! "
64
+ "gvafpscounter starting-frame=500 ! "
68
65
"gvadetect "
69
66
" {detection_model_config} "
70
67
" model-instance-id=detect0 "
@@ -73,16 +70,13 @@ def __init__(self):
73
70
" batch-size={object_detection_batch_size} "
74
71
" inference-interval={object_detection_inference_interval} "
75
72
" nireq={object_detection_nireq} ! "
76
- "queue2 "
77
- " max-size-buffers=0 "
78
- " max-size-bytes=0 "
79
- " max-size-time=0 ! "
73
+ "queue2 ! "
80
74
"gvatrack "
81
75
" tracking-type=short-term-imageless ! "
82
- "queue2 "
83
- " max-size-buffers=0 "
84
- " max-size-bytes=0 "
85
- " max-size-time=0 ! "
76
+ "queue2 ! "
77
+ )
78
+
79
+ self . _inference_stream_classify = (
86
80
"gvaclassify "
87
81
" {classification_model_config} "
88
82
" model-instance-id=classify0 "
@@ -92,19 +86,24 @@ def __init__(self):
92
86
" inference-interval={object_classification_inference_interval} "
93
87
" nireq={object_classification_nireq} "
94
88
" reclassify-interval={object_classification_reclassify_interval} ! "
95
- "queue2 "
96
- " max-size-buffers=0 "
97
- " max-size-bytes=0 "
98
- " max-size-time=0 ! "
99
- "gvawatermark ! "
89
+ "queue2 ! "
90
+ )
91
+
92
+ self ._inference_stream_metadata_processing = (
100
93
"gvametaconvert "
101
94
" format=json "
102
95
" json-indent=4 "
103
96
" source={VIDEO_PATH} ! "
104
97
"gvametapublish "
105
98
" method=file "
106
99
" file-path=/dev/null ! "
107
- "queue2 max-size-bytes=0 max-size-time=0 ! "
100
+ )
101
+
102
+ self ._sink_to_compositor = (
103
+ "queue2 "
104
+ " max-size-buffers={max_size_buffers} "
105
+ " max-size-bytes=0 "
106
+ " max-size-time=0 ! "
108
107
"{postprocessing} ! "
109
108
"video/x-raw,width=640,height=360 ! "
110
109
"comp.sink_{id} "
@@ -240,18 +239,15 @@ def evaluate(
240
239
),
241
240
)
242
241
243
- # Create the compositor
244
- compositor = self ._compositor .format (
245
- ** constants ,
246
- sinks = sinks ,
247
- encoder = _encoder_element ,
248
- compositor = _compositor_element ,
249
- )
242
+
250
243
251
244
# Create the streams
252
245
streams = ""
253
246
247
+ # Handle inference channels
254
248
for i in range (inference_channels ):
249
+
250
+ # Handle object detection parameters and constants
255
251
detection_model_config = (
256
252
f"model={ constants ["OBJECT_DETECTION_MODEL_PATH" ]} "
257
253
f"model-proc={ constants ["OBJECT_DETECTION_MODEL_PROC" ]} "
@@ -262,26 +258,54 @@ def evaluate(
262
258
f"model={ constants ["OBJECT_DETECTION_MODEL_PATH" ]} "
263
259
)
264
260
265
- classification_model_config = (
266
- f"model={ constants ["OBJECT_CLASSIFICATION_MODEL_PATH" ]} "
267
- f"model-proc={ constants ["OBJECT_CLASSIFICATION_MODEL_PROC" ]} "
261
+ streams += self ._inference_stream_decode_detect_track .format (
262
+ ** parameters ,
263
+ ** constants ,
264
+ id = i ,
265
+ decoder = _decoder_element ,
266
+ detection_model_config = detection_model_config ,
268
267
)
269
268
270
- if not constants ["OBJECT_CLASSIFICATION_MODEL_PROC" ]:
269
+ # Handle object classification parameters and constants
270
+ # Do this only if the object classification model is not disabled or the device is not disabled
271
+ if not (constants ["OBJECT_CLASSIFICATION_MODEL_PATH" ] == "Disabled"
272
+ or parameters ["object_classification_device" ] == "Disabled" ) :
271
273
classification_model_config = (
272
274
f"model={ constants ["OBJECT_CLASSIFICATION_MODEL_PATH" ]} "
275
+ f"model-proc={ constants ["OBJECT_CLASSIFICATION_MODEL_PROC" ]} "
273
276
)
274
277
275
- streams += self ._inference_stream .format (
278
+ if not constants ["OBJECT_CLASSIFICATION_MODEL_PROC" ]:
279
+ classification_model_config = (
280
+ f"model={ constants ["OBJECT_CLASSIFICATION_MODEL_PATH" ]} "
281
+ )
282
+
283
+ streams += self ._inference_stream_classify .format (
284
+ ** parameters ,
285
+ ** constants ,
286
+ id = i ,
287
+ classification_model_config = classification_model_config ,
288
+ )
289
+
290
+ # Overlay inference results on the inferenced video if enabled
291
+ if parameters ["pipeline_watermark_enabled" ]:
292
+ streams += "gvawatermark ! "
293
+
294
+ streams += self ._inference_stream_metadata_processing .format (
276
295
** parameters ,
277
296
** constants ,
278
297
id = i ,
279
- decoder = _decoder_element ,
280
- postprocessing = _postprocessing_element ,
281
- detection_model_config = detection_model_config ,
282
- classification_model_config = classification_model_config ,
283
298
)
284
299
300
+ # sink to compositor or fake sink depending on the compose flag
301
+ streams += self ._sink_to_compositor .format (
302
+ ** parameters ,
303
+ ** constants ,
304
+ id = i ,
305
+ postprocessing = _postprocessing_element ,
306
+ max_size_buffers = 0 ,
307
+ )
308
+ # Handle regular channels
285
309
for i in range (inference_channels , channels ):
286
310
streams += self ._recording_stream .format (
287
311
** parameters ,
@@ -290,6 +314,21 @@ def evaluate(
290
314
decoder = _decoder_element ,
291
315
postprocessing = _postprocessing_element ,
292
316
)
317
+ # sink to compositor or fake sink depending on the compose flag
318
+ streams += self ._sink_to_compositor .format (
319
+ ** parameters ,
320
+ ** constants ,
321
+ id = i ,
322
+ postprocessing = _postprocessing_element ,
323
+ max_size_buffers = 1 ,
324
+ )
325
+ # Prepend the compositor
326
+ streams = self ._compositor .format (
327
+ ** constants ,
328
+ sinks = sinks ,
329
+ encoder = _encoder_element ,
330
+ compositor = _compositor_element ,
331
+ ) + streams
293
332
294
333
# Evaluate the pipeline
295
- return "gst-launch-1.0 -q " + compositor + " " + streams
334
+ return "gst-launch-1.0 -q " + streams
0 commit comments