-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
#!/usr/bin/env python3 | ||
import platform | ||
import sys | ||
|
||
sys.path.append('../../') | ||
|
||
import cv2 | ||
import gi | ||
|
||
gi.require_version('Gst', '1.0') | ||
from gi.repository import GLib, Gst | ||
import pyds | ||
|
||
|
||
def is_aarch64(): | ||
return platform.uname()[4] == 'aarch64' | ||
|
||
|
||
def bus_call(bus, message, loop): | ||
t = message.type | ||
if t == Gst.MessageType.EOS: | ||
sys.stdout.write("End-of-stream\n") | ||
loop.quit() | ||
elif t == Gst.MessageType.WARNING: | ||
err, debug = message.parse_warning() | ||
sys.stderr.write("Warning: %s: %s\n" % (err, debug)) | ||
elif t == Gst.MessageType.ERROR: | ||
err, debug = message.parse_error() | ||
sys.stderr.write("Error: %s: %s\n" % (err, debug)) | ||
loop.quit() | ||
return True | ||
|
||
|
||
def pad_buffer_probe(pad: Gst.Pad, info: Gst.PadProbeInfo): | ||
gst_buffer: Gst.Buffer = info.get_buffer() | ||
gpu_mat = cv2.savant.createGpuMat(hash(gst_buffer), 0) | ||
gpu_mat.rowRange(100, 400).colRange(300, 308).setTo((0, 196, 196, 255)) | ||
gpu_mat.rowRange(100, 400).colRange(792, 800).setTo((0, 196, 196, 255)) | ||
gpu_mat.rowRange(100, 108).colRange(300, 800).setTo((0, 196, 196, 255)) | ||
gpu_mat.rowRange(392, 400).colRange(300, 800).setTo((0, 196, 196, 255)) | ||
|
||
gpu_mat.rowRange(300, 500).colRange(350, 358).setTo((196, 196, 0, 255)) | ||
gpu_mat.rowRange(300, 500).colRange(742, 750).setTo((196, 196, 0, 255)) | ||
gpu_mat.rowRange(300, 308).colRange(350, 750).setTo((196, 196, 0, 255)) | ||
gpu_mat.rowRange(492, 500).colRange(350, 750).setTo((196, 196, 0, 255)) | ||
|
||
return Gst.PadProbeReturn.OK | ||
|
||
|
||
def main(args): | ||
if len(args) > 1: | ||
n_frames = int(args[0]) | ||
else: | ||
n_frames = 1 | ||
|
||
Gst.init(None) | ||
|
||
print("Creating Pipeline") | ||
pipeline = Gst.Pipeline() | ||
is_live = False | ||
|
||
print("Creating streammux") | ||
streammux = Gst.ElementFactory.make("nvstreammux", "streammux") | ||
pipeline.add(streammux) | ||
|
||
print("Creating source") | ||
source = Gst.ElementFactory.make("videotestsrc", "source") | ||
pipeline.add(source) | ||
|
||
print("Creating source converter") | ||
source_converter = Gst.ElementFactory.make("nvvideoconvert", "source-converter") | ||
pipeline.add(source_converter) | ||
|
||
print("Creating source capsfilter") | ||
source_capsfilter = Gst.ElementFactory.make("capsfilter", "source-capsfilter") | ||
pipeline.add(source_capsfilter) | ||
|
||
print("Creating workload") | ||
workload = Gst.ElementFactory.make("identity", "workload") | ||
pipeline.add(workload) | ||
|
||
print("Creating streamdemux") | ||
streamdemux = Gst.ElementFactory.make("nvstreamdemux", "streamdemux") | ||
pipeline.add(streamdemux) | ||
|
||
print("Creating queue") | ||
queue = Gst.ElementFactory.make("queue", "queue") | ||
pipeline.add(queue) | ||
|
||
print("Creating converter") | ||
converter = Gst.ElementFactory.make("nvvideoconvert", "converter") | ||
pipeline.add(converter) | ||
|
||
print("Creating sink_capsfilter") | ||
sink_capsfilter = Gst.ElementFactory.make("capsfilter", "sink_capsfilter") | ||
pipeline.add(sink_capsfilter) | ||
|
||
print("Creating encoder") | ||
encoder = Gst.ElementFactory.make("nvv4l2h264enc", "encoder") | ||
pipeline.add(encoder) | ||
|
||
print("Creating parser") | ||
parser = Gst.ElementFactory.make("h264parse", "parser") | ||
pipeline.add(parser) | ||
|
||
print("Creating sink") | ||
sink = Gst.ElementFactory.make("filesink", "sink") | ||
# sink = Gst.ElementFactory.make("fakesink", "sink") | ||
pipeline.add(sink) | ||
|
||
source.set_property('num-buffers', n_frames) | ||
|
||
if is_live: | ||
streammux.set_property('live-source', 1) | ||
streammux.set_property('width', 1280) | ||
streammux.set_property('height', 720) | ||
streammux.set_property('batch-size', 1) | ||
streammux.set_property('batched-push-timeout', 4000000) | ||
|
||
sink.set_property("sync", 0) | ||
sink.set_property("qos", 0) | ||
sink.set_property("enable-last-sample", 0) | ||
sink.set_property("location", "result.h264") | ||
|
||
if not is_aarch64(): | ||
nv_buf_memory_type = int(pyds.NVBUF_MEM_CUDA_UNIFIED) | ||
source_converter.set_property("nvbuf-memory-type", nv_buf_memory_type) | ||
streammux.set_property("nvbuf-memory-type", nv_buf_memory_type) | ||
converter.set_property("nvbuf-memory-type", nv_buf_memory_type) | ||
|
||
source_capsfilter.set_property( | ||
'caps', | ||
Gst.Caps.from_string( | ||
'video/x-raw(memory:NVMM), format=RGBA, width=1280, height=720' | ||
), | ||
) | ||
sink_capsfilter.set_property( | ||
'caps', | ||
Gst.Caps.from_string( | ||
'video/x-raw(memory:NVMM), format=RGBA, width=480, height=480' | ||
), | ||
) | ||
|
||
print("Linking elements in the Pipeline") | ||
|
||
assert source.link(source_converter) | ||
assert source_converter.link(source_capsfilter) | ||
|
||
assert ( | ||
source_capsfilter.get_static_pad('src').link( | ||
streammux.get_request_pad('sink_0') | ||
) | ||
== Gst.PadLinkReturn.OK | ||
) | ||
|
||
assert streammux.link(workload) | ||
assert workload.link(streamdemux) | ||
|
||
streamdemux_src_pad = streamdemux.get_request_pad('src_0') | ||
streamdemux.get_request_pad('src_1') | ||
streamdemux.get_request_pad('src_2') | ||
streamdemux.get_request_pad('src_3') | ||
# workload_3_sink_pad = workload_3.get_static_pad('sink') | ||
# assert streamdemux_src_pad.link(workload_3_sink_pad) == Gst.PadLinkReturn.OK | ||
queue_sink_pad = queue.get_static_pad('sink') | ||
assert streamdemux_src_pad.link(queue_sink_pad) == Gst.PadLinkReturn.OK | ||
|
||
assert queue.link(converter) | ||
# assert converter.link(sink_capsfilter) | ||
# assert sink_capsfilter.link(sink) | ||
assert converter.link(encoder) | ||
assert encoder.link(parser) | ||
assert parser.link(sink) | ||
# assert streammux.link(sink) | ||
|
||
# create an event loop and feed gstreamer bus messages to it | ||
loop = GLib.MainLoop() | ||
bus = pipeline.get_bus() | ||
bus.add_signal_watch() | ||
bus.connect("message", bus_call, loop) | ||
|
||
sink_pad = workload.get_static_pad("sink") | ||
if not sink_pad: | ||
sys.stderr.write("Unable to get sink pad") | ||
else: | ||
sink_pad.add_probe(Gst.PadProbeType.BUFFER, pad_buffer_probe) | ||
|
||
print("Starting pipeline") | ||
pipeline.set_state(Gst.State.PLAYING) | ||
try: | ||
loop.run() | ||
except: | ||
pass | ||
print("Exiting app\n") | ||
pipeline.set_state(Gst.State.NULL) | ||
|
||
|
||
if __name__ == '__main__': | ||
sys.exit(main(sys.argv)) |