diff --git a/gstreamer/gstreamer.py b/gstreamer/gstreamer.py index 9770e09..2676439 100644 --- a/gstreamer/gstreamer.py +++ b/gstreamer/gstreamer.py @@ -21,14 +21,13 @@ gi.require_version('Gtk', '3.0') from gi.repository import GLib, GObject, Gst, GstBase, Gtk -GObject.threads_init() Gst.init(None) class GstPipeline: def __init__(self, pipeline, user_function, src_size): self.user_function = user_function self.running = False - self.gstbuffer = None + self.gstsample = None self.sink_size = None self.src_size = src_size self.box = None @@ -36,9 +35,12 @@ def __init__(self, pipeline, user_function, src_size): self.pipeline = Gst.parse_launch(pipeline) self.overlay = self.pipeline.get_by_name('overlay') + self.gloverlay = self.pipeline.get_by_name('gloverlay') self.overlaysink = self.pipeline.get_by_name('overlaysink') + appsink = self.pipeline.get_by_name('appsink') - appsink.connect('new-sample', self.on_new_sample) + appsink.connect('new-preroll', self.on_new_sample, True) + appsink.connect('new-sample', self.on_new_sample, False) # Set up a pipeline bus watch to catch errors. bus = self.pipeline.get_bus() @@ -83,13 +85,13 @@ def on_bus_message(self, bus, message): Gtk.main_quit() return True - def on_new_sample(self, sink): - sample = sink.emit('pull-sample') + def on_new_sample(self, sink, preroll): + sample = sink.emit('pull-preroll' if preroll else 'pull-sample') if not self.sink_size: s = sample.get_caps().get_structure(0) self.sink_size = (s.get_value('width'), s.get_value('height')) with self.condition: - self.gstbuffer = sample.get_buffer() + self.gstsample = sample self.condition.notify_all() return Gst.FlowReturn.OK @@ -113,18 +115,21 @@ def get_box(self): def inference_loop(self): while True: with self.condition: - while not self.gstbuffer and self.running: + while not self.gstsample and self.running: self.condition.wait() if not self.running: break - gstbuffer = self.gstbuffer - self.gstbuffer = None + gstsample = self.gstsample + self.gstsample = None # Passing Gst.Buffer as input tensor avoids 2 copies of it. + gstbuffer = gstsample.get_buffer() svg = self.user_function(gstbuffer, self.src_size, self.get_box()) if svg: if self.overlay: self.overlay.set_property('data', svg) + if self.gloverlay: + self.gloverlay.emit('set-svg', svg, gstbuffer.pts) if self.overlaysink: self.overlaysink.set_property('svg', svg) @@ -187,13 +192,15 @@ def on_bus_message_sync(bus, message, overlaysink): bus = self.pipeline.get_bus() bus.set_sync_handler(on_bus_message_sync, self.overlaysink) -def detectCoralDevBoard(): +def get_dev_board_model(): try: - if 'MX8MQ' in open('/sys/firmware/devicetree/base/model').read(): - print('Detected Edge TPU dev board.') - return True + model = open('/sys/firmware/devicetree/base/model').read().lower() + if 'mx8mq' in model: + return 'mx8mq' + if 'mt8167' in model: + return 'mt8167' except: pass - return False + return None def run_pipeline(user_function, src_size, @@ -219,12 +226,23 @@ def run_pipeline(user_function, ! videoconvert n-threads=4 ! videoscale n-threads=4 ! {src_caps} ! {leaky_q} """ % (videosrc, demux) - if detectCoralDevBoard(): - scale_caps = None - PIPELINE += """ ! decodebin ! glupload ! tee name=t - t. ! queue ! glfilterbin filter=glbox name=glbox ! {sink_caps} ! {sink_element} - t. ! queue ! glsvgoverlaysink name=overlaysink - """ + coral = get_dev_board_model() + if coral: + if 'mt8167' in coral: + PIPELINE += """ ! decodebin ! queue ! v4l2convert ! {scale_caps} ! + glupload ! glcolorconvert ! video/x-raw(memory:GLMemory),format=RGBA ! + tee name=t + t. ! queue ! glfilterbin filter=glbox name=glbox ! queue ! {sink_caps} ! {sink_element} + t. ! queue ! glsvgoverlay name=gloverlay sync=false ! glimagesink fullscreen=true + qos=false sync=false + """ + scale_caps = 'video/x-raw,format=BGRA,width={w},height={h}'.format(w=src_size[0], h=src_size[1]) + else: + PIPELINE += """ ! decodebin ! glupload ! tee name=t + t. ! queue ! glfilterbin filter=glbox name=glbox ! {sink_caps} ! {sink_element} + t. ! queue ! glsvgoverlaysink name=overlaysink + """ + scale_caps = None else: scale = min(appsink_size[0] / src_size[0], appsink_size[1] / src_size[1]) scale = tuple(int(x * scale) for x in src_size) diff --git a/gstreamer/install_requirements.sh b/gstreamer/install_requirements.sh index 9e9cd6d..7c13f84 100644 --- a/gstreamer/install_requirements.sh +++ b/gstreamer/install_requirements.sh @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -if grep -s -q "MX8MQ" /sys/firmware/devicetree/base/model; then +if grep -s -q "Mendel" /etc/os-release; then echo "No DevBoard specific dependencies" else # Install gstreamer diff --git a/opencv/install_requirements.sh b/opencv/install_requirements.sh index 292be97..6cf0766 100755 --- a/opencv/install_requirements.sh +++ b/opencv/install_requirements.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -if grep -s -q "MX8MQ" /sys/firmware/devicetree/base/model; then +if grep -s -q "Mendel" /etc/os-release; then MENDEL_VER="$(cat /etc/mendel_version)" if [[ "$MENDEL_VER" == "1.0" || "$MENDEL_VER" == "2.0" || "$MENDEL_VER" == "3.0" ]]; then echo "Your version of Mendel is not compatible with OpenCV." diff --git a/pygame/detect.py b/pygame/detect.py index 19b9904..bd361df 100644 --- a/pygame/detect.py +++ b/pygame/detect.py @@ -63,8 +63,20 @@ def main(): inference_size = input_size(interpreter) - print('By default using camera: ', camlist[-1]) - camera = pygame.camera.Camera(camlist[-1], (cam_w, cam_h)) + camera = None + for cam in camlist: + try: + camera = pygame.camera.Camera(cam, (cam_w, cam_h)) + camera.start() + print(str(cam) + ' opened') + break + except SystemError as e: + print('Failed to open {}: {}'.format(str(cam), str(e))) + camera = None + if not camera: + sys.stderr.write("\nERROR: Unable to open a camera.\n") + sys,exit(1) + try: display = pygame.display.set_mode((cam_w, cam_h), 0) except pygame.error as e: @@ -75,7 +87,6 @@ def main(): red = pygame.Color(255, 0, 0) - camera.start() scale_x, scale_y = cam_w / inference_size[0], cam_h / inference_size[1] try: last_time = time.monotonic() @@ -98,7 +109,7 @@ def main(): text = font.render(label, True, red) print(label, ' ', end='') mysurface.blit(text, (bbox.xmin, bbox.ymin)) - text = font.render(annotate_text, True, red) + text = font.render(annotate_text, True, red) print(annotate_text) mysurface.blit(text, (0, 0)) display.blit(mysurface, (0, 0)) diff --git a/pygame/install_requirements.sh b/pygame/install_requirements.sh index e12a124..aff4a10 100644 --- a/pygame/install_requirements.sh +++ b/pygame/install_requirements.sh @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -if grep -s -q "MX8MQ" /sys/firmware/devicetree/base/model; then +if grep -s -q "Mendel" /etc/os-release; then echo "Installing DevBoard specific dependencies" sudo apt-get install -y python3-pygame else