├── README.md ├── REVIEW.md ├── archive ├── .ipynb_checkpoints │ ├── 01-checkpoint.ipynb │ ├── 02-checkpoint.ipynb │ ├── 03-checkpoint.ipynb │ └── 04-checkpoint.ipynb ├── 01.ipynb ├── 02.ipynb ├── 03.ipynb ├── 04.ipynb ├── 05.ipynb ├── 06.ipynb ├── 07.ipynb ├── 08.ipynb ├── README.md ├── docker_run.sh ├── sample_stream │ ├── sample_1080p_h264.mp4 │ ├── sample_1080p_h265.mp4 │ └── sample_720p.h264 ├── system_setup.sh └── test1 │ ├── README │ ├── common │ ├── FPS.py │ ├── __init__.py │ ├── __pycache__ │ │ ├── FPS.cpython-36.pyc │ │ ├── __init__.cpython-36.pyc │ │ ├── bus_call.cpython-36.pyc │ │ └── is_aarch_64.cpython-36.pyc │ ├── bus_call.py │ ├── is_aarch_64.py │ └── utils.py │ ├── deepstream_test_1.py │ ├── dstest1_pgie_config.txt │ ├── pipeline1.py │ ├── pipeline2.py │ ├── pipeline2b.py │ ├── pipeline3.py │ └── pipeline4.py ├── asset ├── CV.jpg ├── ML.jpg ├── computer_vision_with_embedded_ml.png ├── cover_image.jpeg ├── intro_to_embedded_ml.png ├── making-things-smarter.png ├── week3-tasks.png ├── week3_reading.png ├── week4-tasks.png └── week4_reading.png ├── week1 └── README.md ├── week2 ├── README.md └── setup.sh ├── week3 └── README.md └── week4 ├── README.md ├── deepstream-old.sh ├── deepstream_no_display.sh └── jetson.sh /README.md: -------------------------------------------------------------------------------- 1 | # AI6LAGOS EDGE COMPUTING WORKSHOP 2023 2 | ![Cover Image](./asset/cover_image.jpeg) 3 | The workshop is designed to foster an enabling environment for individuals to build competence in the Edge Computing space. At the end of the program, individuals will be able to deploy models on Nvidia Jetson devices and create custom models using the Edge Impulse platform. 4 | 5 | | Week | Date | Task | Duration | 6 | |-----|------|------|------| 7 | | 1 | May 20th | Introduction to Edge Compute | 1hr | 8 | | | | Setting Up your Jetson Nano | 2hr | 9 | | 2 | May 27th | Introduction to Image classification | 1hr | 10 | | | | Image classification on Jetson using Edge Impulse | 2hr | 11 | | 3 | June 3rd | Introduction to Image Regression | 1hr | 12 | | | | Image Regression with on Jetson Nano | 2hr | 13 | | 4 | June 10th | Custom deploying on Jetson Nano using Edge Impulse | 2hr | 14 | | | | Introduction to Gstreamer/Deepstream | 1hr | 15 | | | | Issuing Certification at the end of the program | 10-30min | 16 | 17 | 18 | ## Course, Platform and Tools 19 | - [Getting Started with AI on Jetson](https://courses.nvidia.com/courses/course-v1:DLI+S-RX-02+V2/) 20 | - [Edge Impulse](https://www.edgeimpulse.com/) 21 | - [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) 22 | 23 | 24 | ## Basic Requirements 25 | - Basic knowledge of python(variable, function, etc) 26 | - Knowledge/Interest in computer vision 27 | - An element of curiosity 28 | 29 | ## What you are expected to gain from the program 30 | - Learn how to use building models using Edge Impulse and deploy your models on Jetson Nano 31 | - Learn how to use Docker, Numpy, Pandas, Jupyter Notebook etc 32 | - Learn how to build custom models 33 | - Nvidia Deep Learning Certificate 34 | 35 | Workshop Material 36 | - [Week 1](https://docs.google.com/presentation/d/1Ife9oXupc0jdurz8OpKKgqQfPycReCQJTC5_gqc5L3c/edit#slide=id.g244451957ee_0_1014) 37 | - [Week 2](https://docs.google.com/presentation/d/1XWsyqMV0qWNydiazBFBhmSQ0RGoVfbG9RR_gB1fk6YA/edit#slide=id.g2461e0ba8aa_0_302) 38 | - [Week 3](https://docs.google.com/presentation/d/1XysQ0LZNVrypUVlZAcyLiS--wj4eDBu0-68UC2j6WkQ/edit#slide=id.g513673c178480d1c_20) 39 | - [Speaker: Optimization and Compression Techniques for Learning Algorithms by Kenechi Ojukwu](https://docs.google.com/presentation/d/1S-ZIHDx9WzdQFYBJuQIuuCc5LzM9J6pQ/edit#slide=id.p1) 40 | - [Week 4](https://docs.google.com/presentation/d/1m89Nup74u7-iZTI3vDBtCeZ23v7RCVLYC6LeTTCwYe4/edit#slide=id.g513673c178480d1c_20) 41 | - [Speaker: __ by __]() 42 | 43 | 44 | ## Reference 45 | - [Nvidia Deep Learning Institute](https://courses.nvidia.com/courses/course-v1:DLI+S-FX-01+V1/) 46 | - [Book: AI at the edge](https://www.oreilly.com/library/view/ai-at-the/9781098120191/) 47 | - [Installation of Edge Impulse](https://docs.edgeimpulse.com/docs/edge-impulse-cli/cli-installation) 48 | - [Article: What Is Edge AI and How Does It Work?](https://blogs.nvidia.com/blog/2022/02/17/what-is-edge-ai/) 49 | - [Workshop advantech Jetson Nano](https://github.com/edgeimpulse/workshop-advantech-jetson-nano) 50 | - [Machine Learning at the Network Edge: A Survey](https://arxiv.org/pdf/1908.00080.pdf) 51 | - [Edge AI 101- What is it, Why is it important, and How to implement Edge AI?](https://www.seeedstudio.com/blog/2021/04/02/edge-ai-what-is-it-and-what-can-it-do-for-edge-iot/) 52 | - [Edge Computing Fuels a Sustainable Future for Energy](https://developer.nvidia.com/blog/edge-computing-fuels-a-sustainable-future-for-energy/#:~:text=Oil%20and%20gas%20enterprises%20and,sources%20of%20energy%20to%20consumers.) 53 | - [Manufacturing the Future of AI with Edge Computing](https://developer.nvidia.com/blog/manufacturing-the-future-of-ai-with-edge-computing/) 54 | - [AI Personalizes Online Shopping](https://developer.nvidia.com/blog/top-3-pillars-of-ai-enabled-edge-computing-in-retail/) -------------------------------------------------------------------------------- /REVIEW.md: -------------------------------------------------------------------------------- 1 | # Edge Computing Workshop 2 | 3 | The workshop is designed to foster an enabling environment for individuals to build competence in the Edge Computing space. At the end of the program individuals will be able to deploy models on Nvidia Jetson devices for video Analytics, Conservational AI and Data Science solutions. 4 | # 5 | 6 | 7 | ## Content 8 | - Fundamental of Edge Computing 9 | - Roadmap to Building Video AI Applications at the Edge on Jetson Nano 10 | - Setting up your Jetson Nano - [Link](https://courses.nvidia.com/courses/course-v1:DLI+S-RX-02+V2/about) 11 | - Introduction to Deepstream - [Link](https://courses.nvidia.com/courses/course-v1:DLI+L-IV-04+V1/about) 12 | - Exploring Deepstream SDK - [Link](https://courses.nvidia.com/courses/course-v1:DLI+S-IV-01+V1/about) 13 | - Projects with Edge Computing: 14 | - Video Analytics using Deepstream SDK - [Link](https://courses.nvidia.com/courses/course-v1:DLI+S-IV-02+V2/about) 15 | - Conservational AI 16 | - Data Science 17 | - Training models for Edge computing 18 | - Quantization and Optimization of Tensorflow model using TensorRT 19 | - DevOps in Edge computing(Docker, Docker-Compose, Kubernetes (k3s) etc) 20 | - Integrating Edge computing with Messaging system (Kafka/MQTT) 21 | - Integrating Edge computing with Webrtc 22 | - Integrating Edge device with external devices: 23 | - Lidar 24 | - Depth/Stereo Sensor 25 | -------------------------------------------------------------------------------- /archive/.ipynb_checkpoints/01-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "5367f1e9-1543-45d4-849f-a6aad602f596", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "gst-inspect-1.0 version 1.14.5\n", 14 | "GStreamer 1.14.5\n", 15 | "https://launchpad.net/distros/ubuntu/+source/gstreamer1.0\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "# Check Gstreamer version \n", 21 | "!gst-inspect-1.0 --version" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "id": "c5bde50c-edda-4a30-a815-9740af438137", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "\n", 35 | "(gst-launch-1.0:447): GStreamer-\u001b[1;33mWARNING\u001b[0m **: \u001b[34m21:36:48.458\u001b[0m: 0.10-style raw video caps are being created. Should be video/x-raw,format=(string).. now.\n", 36 | "WARNING: erroneous pipeline: could not link v4l2src0 to autovideosink0, v4l2src0 can't handle caps video/x-raw-yuv, width=(int)320, height=(int)240\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "!gst-launch-1.0 v4l2src ! 'video/x-raw-yuv,width=320,height=240' ! autovideosink" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 3, 47 | "id": "51928db0-dda4-4e59-85b2-a13c3a99bdf0", 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "Factory Details:\n", 55 | " Rank none (0)\n", 56 | " Long-name Auto video sink\n", 57 | " Klass Sink/Video\n", 58 | " Description Wrapper video sink for automatically detected video sink\n", 59 | " Author Jan Schmidt \n", 60 | "\n", 61 | "Plugin Details:\n", 62 | " Name autodetect\n", 63 | " Description Plugin contains auto-detection plugins for video/audio in- and outputs\n", 64 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstautodetect.so\n", 65 | " Version 1.14.5\n", 66 | " License LGPL\n", 67 | " Source module gst-plugins-good\n", 68 | " Source release date 2019-05-29\n", 69 | " Binary package GStreamer Good Plugins (Ubuntu)\n", 70 | " Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-good1.0\n", 71 | "\n", 72 | "GObject\n", 73 | " +----GInitiallyUnowned\n", 74 | " +----GstObject\n", 75 | " +----GstElement\n", 76 | " +----GstBin\n", 77 | " +----GstAutoDetect\n", 78 | " +----GstAutoVideoSink\n", 79 | "\n", 80 | "Implemented Interfaces:\n", 81 | " GstChildProxy\n", 82 | "\n", 83 | "Pad Templates:\n", 84 | " SINK template: 'sink'\n", 85 | " Availability: Always\n", 86 | " Capabilities:\n", 87 | " ANY\n", 88 | "\n", 89 | "Element has no clocking capabilities.\n", 90 | "Element has no URI handling capabilities.\n", 91 | "\n", 92 | "Pads:\n", 93 | " SINK: 'sink'\n", 94 | "\n", 95 | "Element Properties:\n", 96 | " name : The name of the object\n", 97 | " flags: readable, writable\n", 98 | " String. Default: \"autovideosink0\"\n", 99 | " parent : The parent of the object\n", 100 | " flags: readable, writable\n", 101 | " Object of type \"GstObject\"\n", 102 | " async-handling : The bin will handle Asynchronous state changes\n", 103 | " flags: readable, writable\n", 104 | " Boolean. Default: false\n", 105 | " message-forward : Forwards all children messages\n", 106 | " flags: readable, writable\n", 107 | " Boolean. Default: false\n", 108 | " filter-caps : Filter sink candidates using these caps.\n", 109 | " flags: readable, writable\n", 110 | " video/x-raw\n", 111 | "\n", 112 | " sync : Sync on the clock\n", 113 | " flags: readable, writable\n", 114 | " Boolean. Default: true\n", 115 | " ts-offset : Timestamp offset in nanoseconds\n", 116 | " flags: readable, writable\n", 117 | " Integer64. Range: -9223372036854775808 - 9223372036854775807 Default: 0 \n", 118 | "\n", 119 | "Children:\n", 120 | " fake-video-sink\n" 121 | ] 122 | } 123 | ], 124 | "source": [ 125 | "!gst-inspect-1.0 autovideosink" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 6, 131 | "id": "d4ee5463-f66a-4df6-9553-2034a86d0c2c", 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "#!GST_DEBUG=*:3 gst-launch-1.0 filesrc location=../../../../../samples/streams/sample_1080p_h264.mp4 ! qtdemux name=demux ! h264parse ! omxh264dec ! nveglglessink -e" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 8, 141 | "id": "27b2e625-fa20-45b8-a4af-2144f5d5df9a", 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "# !gst-launch-1.0 filesrc location=\"../../../../../samples/streams/sample_1080p_h264.mp4\" ! \\\n", 146 | "# qtdemux name=demux demux.video_0 ! queue ! h264parse ! omxh264dec ! \\\n", 147 | "# nveglglessink -e" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 12, 153 | "id": "261196d7-6ad6-4374-bd70-49ff4d8e1456", 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "name": "stdout", 158 | "output_type": "stream", 159 | "text": [ 160 | "Setting pipeline to PAUSED ...\n", 161 | "Pipeline is PREROLLING ...\n", 162 | "Pipeline is PREROLLED ...\n", 163 | "Setting pipeline to PLAYING ...\n", 164 | "New clock: GstSystemClock\n", 165 | "Got EOS from element \"pipeline0\".\n", 166 | "Execution ended after 0:00:00.005621141\n", 167 | "Setting pipeline to PAUSED ...\n", 168 | "Setting pipeline to READY ...\n", 169 | "Setting pipeline to NULL ...\n", 170 | "Freeing pipeline ...\n" 171 | ] 172 | } 173 | ], 174 | "source": [ 175 | "!gst-launch-1.0 videotestsrc num-buffers=4 ! jpegenc ! \\\n", 176 | " filesink location=videotestsrc-frame.jpg" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 13, 182 | "id": "0d68ac07-73eb-44d7-a2cf-66d6fe1ae23c", 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCADwAUADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD6rooooAKKKKACqGuf8ei/9dB/I1fqhrn/AB6L/wBdB/I187xZ/wAibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/5CUf/AFxH82rqK5fxb/yEo/8AriP5tX6X4S/8lFH/AAS/I/PvE3/kRS/xRMeiiiv6lP5wCiiigArnLv8A4+5v+ujfzNdHXOXf/H3N/wBdG/ma/MPE/wD3Sh/if5HZgviZFRRRX42eiFFFFAFDxD/yBp/+A/8AoQrkK6/xD/yBp/8AgP8A6EK5Cv6U8G/+RHV/6+y/9Igf154Af8k5X/6/S/8ASKYUUUV+sH7gFFFFAGXr3/LH/gX9Ky61Ne/5Y/8AAv6Vl1/PPHX/ACPq/wD27/6RE9bDfwkFFFFfJG4UUUUAcf4i/wCQzP8A8B/9BFZ9aHiL/kMz/wDAf/QRWfX9pcK/8iPBf9eqf/pCP5J4k/5HGL/6+T/9KYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/49F/66D+Rr53iz/kTYj/AAmtD+IjGooor+bj2AooooAK5fxb/wAhKP8A64j+bV1Fcv4t/wCQlH/1xH82r9L8Jf8Akoo/4Jfkfn3ib/yIpf4omPRRRX9Sn84BRRRQAVzl3/x9zf8AXRv5mujrnLv/AI+5v+ujfzNfmHif/ulD/E/yOzBfEyKiiivxs9EKKKKAKHiH/kDT/wDAf/QhXIV1/iH/AJA0/wDwH/0IVyFf0p4N/wDIjq/9fZf+kQP688AP+Scr/wDX6X/pFMKKKK/WD9wCiiigDL17/lj/AMC/pWXWpr3/ACx/4F/Ssuv5546/5H1f/t3/ANIiethv4SCiiivkjcKKKKAOP8Rf8hmf/gP/AKCKz60PEX/IZn/4D/6CKz6/tLhX/kR4L/r1T/8ASEfyTxJ/yOMX/wBfJ/8ApTCiiivePFCiiigD9NqKKK/kw90KKKKACqGuf8ei/wDXQfyNX6oa5/x6L/10H8jXzvFn/ImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/1xH82rqK5fxb/yEo/+uI/m1fpfhL/yUUf8EvyPz7xN/wCRFL/FEx6KKK/qU/nAKKKKACucu/8Aj7m/66N/M10dc5d/8fc3/XRv5mvzDxP/AN0of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/wDIGn/4D/6EK5Cuv8Q/8gaf/gP/AKEK5Cv6U8G/+RHV/wCvsv8A0iB/XngB/wAk5X/6/S/9IphRRRX6wfuAUUUUAZevf8sf+Bf0rLrU17/lj/wL+lZdfzzx1/yPq/8A27/6RE9bDfwkFFFFfJG4UUUUAcf4i/5DM/8AwH/0EVn1oeIv+QzP/wAB/wDQRWfX9pcK/wDIjwX/AF6p/wDpCP5J4k/5HGL/AOvk/wD0phRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP+PRf+ug/kav1Q1z/AI9F/wCug/ka+d4s/wCRNiP8JrQ/iIxqKKK/m49gKKKKACuX8W/8hKP/AK4j+bV1Fcv4t/5CUf8A1xH82r9L8Jf+Sij/AIJfkfn3ib/yIpf4omPRRRX9Sn84BRRRQAVzl3/x9zf9dG/ma6Oucu/+Pub/AK6N/M1+YeJ/+6UP8T/I7MF8TIqKKK/Gz0QooooAoeIf+QNP/wAB/wDQhXIV1/iH/kDT/wDAf/QhXIV/Sng3/wAiOr/19l/6RA/rzwA/5Jyv/wBfpf8ApFMKKKK/WD9wCiiigDL17/lj/wAC/pWXWpr3/LH/AIF/Ssuv5546/wCR9X/7d/8ASInrYb+Egooor5I3CiiigDj/ABF/yGZ/+A/+gis+tDxF/wAhmf8A4D/6CKz6/tLhX/kR4L/r1T/9IR/JPEn/ACOMX/18n/6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/AB6L/wBdB/I1fqhrn/Hov/XQfyNfO8Wf8ibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/wCQlH/1xH82rqK5fxb/AMhKP/riP5tX6X4S/wDJRR/wS/I/PvE3/kRS/wAUTHooor+pT+cAooooAK5y7/4+5v8Aro38zXR1zl3/AMfc3/XRv5mvzDxP/wB0of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8AIGn/AOA/+hCuQrr/ABD/AMgaf/gP/oQrkK/pTwb/AORHV/6+y/8ASIH9eeAH/JOV/wDr9L/0imFFFFfrB+4BRRRQBl69/wAsf+Bf0rLrU17/AJY/8C/pWXX888df8j6v/wBu/wDpET1sN/CQUUUV8kbhRRRQBx/iL/kMz/8AAf8A0EVn1oeIv+QzP/wH/wBBFZ9f2lwr/wAiPBf9eqf/AKQj+SeJP+Rxi/8Ar5P/ANKYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/49F/66D+Rr53iz/kTYj/Ca0P4iMaiiiv5uPYCiiigArl/Fv/ISj/64j+bV1Fcv4t/5CUf/AFxH82r9L8Jf+Sij/gl+R+feJv8AyIpf4omPRRRX9Sn84BRRRQAVzl3/AMfc3/XRv5mujrnLv/j7m/66N/M1+YeJ/wDulD/E/wAjswXxMiooor8bPRCiiigCh4h/5A0//Af/AEIVyFdf4h/5A0//AAH/ANCFchX9KeDf/Ijq/wDX2X/pED+vPAD/AJJyv/1+l/6RTCiiiv1g/cAooooAy9e/5Y/8C/pWXWpr3/LH/gX9Ky6/nnjr/kfV/wDt3/0iJ62G/hIKKKK+SNwooooA4/xF/wAhmf8A4D/6CKz60PEX/IZn/wCA/wDoIrPr+0uFf+RHgv8Ar1T/APSEfyTxJ/yOMX/18n/6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/Hov/XQfyNX6oa5/x6L/ANdB/I187xZ/yJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/kJR/wDXEfzauorl/Fv/ACEo/wDriP5tX6X4S/8AJRR/wS/I/PvE3/kRS/xRMeiiiv6lP5wCiiigArnLv/j7m/66N/M10dc5d/8AH3N/10b+Zr8w8T/90of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8gaf/AID/AOhCuQrr/EP/ACBp/wDgP/oQrkK/pTwb/wCRHV/6+y/9Igf154Af8k5X/wCv0v8A0imFFFFfrB+4BRRRQBl69/yx/wCBf0rLrU17/lj/AMC/pWXX888df8j6v/27/wCkRPWw38JBRRRXyRuFFFFAHH+Iv+QzP/wH/wBBFZ9aHiL/AJDM/wDwH/0EVn1/aXCv/IjwX/Xqn/6Qj+SeJP8AkcYv/r5P/wBKYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/AI9F/wCug/kav1Q1z/j0X/roP5GvneLP+RNiP8JrQ/iIxqKKK/m49gKKKKACuX8W/wDISj/64j+bV1Fcv4t/5CUf/XEfzav0vwl/5KKP+CX5H594m/8AIil/iiY9FFFf1KfzgFFFFABXOXf/AB9zf9dG/ma6Oucu/wDj7m/66N/M1+YeJ/8AulD/ABP8jswXxMiooor8bPRCiiigCh4h/wCQNP8A8B/9CFchXX+If+QNP/wH/wBCFchX9KeDf/Ijq/8AX2X/AKRA/rzwA/5Jyv8A9fpf+kUwooor9YP3AKKKKAMvXv8Alj/wL+lZdamvf8sf+Bf0rLr+eeOv+R9X/wC3f/SInrYb+Egooor5I3CiiigDj/EX/IZn/wCA/wDoIrPrQ8Rf8hmf/gP/AKCKz6/tLhX/AJEeC/69U/8A0hH8k8Sf8jjF/wDXyf8A6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/Hov/XQfyNX6oa5/wAei/8AXQfyNfO8Wf8AImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/wBcR/Nq6iuX8W/8hKP/AK4j+bV+l+Ev/JRR/wAEvyPz7xN/5EUv8UTHooor+pT+cAooooAK5y7/AOPub/ro38zXR1zl3/x9zf8AXRv5mvzDxP8A90of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8gaf/gP/AKEK5Cuv8Q/8gaf/AID/AOhCuQr+lPBv/kR1f+vsv/SIH9eeAH/JOV/+v0v/AEimFFFFfrB+4BRRRQBl69/yx/4F/SsutTXv+WP/AAL+lZdfzzx1/wAj6v8A9u/+kRPWw38JBRRRXyRuFFFFAHH+Iv8AkMz/APAf/QRWfWh4i/5DM/8AwH/0EVn1/aXCv/IjwX/Xqn/6Qj+SeJP+Rxi/+vk//SmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/49F/66D+Rq/VDXP+PRf+ug/ka+d4s/5E2I/wAJrQ/iIxqKKK/m49gKKKKACuX8W/8AISj/AOuI/m1dRXL+Lf8AkJR/9cR/Nq/S/CX/AJKKP+CX5H594m/8iKX+KJj0UUV/Up/OAUUUUAFc5d/8fc3/AF0b+Zro65y7/wCPub/ro38zX5h4n/7pQ/xP8jswXxMiooor8bPRCiiigCh4h/5A0/8AwH/0IVyFdf4h/wCQNP8A8B/9CFchX9KeDf8AyI6v/X2X/pED+vPAD/knK/8A1+l/6RTCiiiv1g/cAooooAy9e/5Y/wDAv6Vl1qa9/wAsf+Bf0rLr+eeOv+R9X/7d/wDSInrYb+Egooor5I3CiiigDj/EX/IZn/4D/wCgis+tDxF/yGZ/+A/+gis+v7S4V/5EeC/69U//AEhH8k8Sf8jjF/8AXyf/AKUwooor3jxQooooAKKKKACiiigAqhrn/Hov/XQfyNX6oa5/x6L/ANdB/I189xZ/yJsR/hNqH8RGNRRRX82nrhRRRQAV618Gf+RXuf8Ar9b/ANASvJa9a+DP/Ir3P/X63/oCV9Lwn/yMV6M+v4H/AORqv8LO2ooor9RP2cKKKKACvAfFX/Iz6r/1+zf+htXv1eA+Kv8AkZ9V/wCv2b/0Nq+M40/gUvV/kfn3iF/u1H/E/wAjNooor88PyoKKKKAO9/Z6/wCSwaH/ANvH/pPJX1zXyN+z1/yWDQ/+3j/0nkr65r6bJf4D9f0R+H+Jf/I1p/8AXtf+lTCiiivXPzwKKKKAPBP2u/8AmWP+3v8A9o14JXvf7Xf/ADLH/b3/AO0a8Er5HM/96n8vyR/Q3Av/ACIaH/b3/pcgooorgPrQooooA/Qf9kL/AJN28Mf9vf8A6VzV6vXlH7IX/Ju3hj/t7/8ASuavV6ACiiigAooooA/LX+1/+nf/AMf/APrUf2v/ANO//j//ANasuiv6B/tbF/z/AIL/ACP53/1uzj/n9/5LH/I1P7X/AOnf/wAf/wDrUf2v/wBO/wD4/wD/AFqy6KP7Wxf8/wCC/wAg/wBbs4/5/f8Aksf8jU/tf/p3/wDH/wD61V76++0wiPytmGzndn19qp0VzYvF1sZRlQrO8ZaNaL8tSo8YZxF3Vb/yWP8A8ieg/AT4af8AC0vGF34f/tr+yPs+nveef9l8/dtkjTbt3rj/AFmc57dOa9u/4Y3/AOqi/wDlE/8At9cn+wR/yWDVv+wBN/6UW9fbdfkOf4SjhMY6dFWjZd3+Z+vcH5jicxy1V8TLmldq9ktvRJHyh/wxv/1UX/yif/b6P+GN/wDqov8A5RP/ALfX1fRXin1B8of8Mb/9VF/8on/2+ut8Gfs1f8I7pctl/wAJn9q3zGXf/ZezGVUYx5p/u/rX0FRXThMZWwdT2tF2l8n+Z2YHH4jAVfbYeXLLa9k/zueMf8KJ/wCpp/8AKf8A/bK+fPi94g/4QD4iap4R+yf2l9g8r/SfM8rzN8KSfcw2Mb8dT0zX3VX58ftef8nEeKP+3T/0khr9F4JzHE5nj50cVLmioN2slreK6Jd2fc8N8R5ljcVKnXqXSi3tFa3XZFD/AIWl/wBQP/yb/wDsKP8AhaX/AFA//Jv/AOwrzeiv1D+zsN/L+L/zPtfrlb+b8j0j/haX/UD/APJv/wCwrgNVuvt2qXd75fl/aJnl2Zzt3MTjPfrVaiuLG8O5djoqNendLzkvyaPOzDDUsxio4lcyW3T8rBRRRXnf6kZH/wA+P/Jp/wDyR5X+reWf8+/xl/mUvt//AEy/8e/+tR9v/wCmX/j3/wBaqVFfz+flZ1nw98Zf8In4wsfEH9nfbfsvmfufP8vdujZPvbTjG7PTtXs0H7SHmxB/+ENxnt/af/2qvm2tOx/49U/H+ddVHGVqEeWnKy+R4eZ8N5ZmlVVsXT5pJWveS0u30a7s+gv+Gjf+pO/8qf8A9qo/4aN/6k7/AMqf/wBqrwSitf7UxX834L/I87/UXIf+fH/k0/8A5I+gLb9ofznK/wDCIbcDP/ISz/7Sqx/wv7/qU/8Ayo//AGuvANN/17f7v9RWhR/amK/m/Bf5B/qLkP8Az4/8mn/8kdj8XvHH/Cf/ANl/8Sz+zfsHnf8ALfzd/mbP9lcY2e/WuC+wf9Nf/Hf/AK9XKK5KtWdWTnN3bPosBgaGAoRw+Hjywjeyu3u7vV3e7PQG+Cd0kuoRv4m07GnQGe7ljXzEiRbcySOwVi4QOpQHb8w2sB86Kzp/gjeTSww6Nrf255IpCvmWLRefIHEaLCAzM6s+/EjKigRuzYAr1HSNQfXtJs7ryXlu7aeVI7i5uWF5YW5l3B4nMjNL/rkjCuZMyPEQ7FCBNa6Z4fl8QjUtHvrrUrjQAf8AiX2YRbqWdXEcTMMmNoQN6sMgpEsRZtpFZnWeXRfA8LYPcah4rj02WK8t7WeC4sGLwee0XlSSbHby0ZHkO59o3Iq9WOzPn+C+rpm0i1KN9UJV0s5bWS3LI3lhQWlC4k/eKSMbFGQzqw217Pq93DJPYaxb3kWuab5L/bbq7lguhZ3bqnyGfhBBGrQuXVXG6HO0ybjHd0LQFuTaxnS9TjaCOKC7XFqUgP2i6Dx7ndgzOj7TwztGpDuC+4gG18I/FrfDr4X2vhm50t9SXR7qa1nvIZgkUbtcszeaWGIuJo9gyWbdyEw23pH+M0v/AAjMGtW/hK5vjNeLGttZ3Jml+zkFmkwsZ+dVAJj6AnbvyCK8mtdTS1v01u8igtmutlq0V6Etre3Md0xAtiGEuI3EcrxDkq0oIyQU2LfXIdOEMU+tRXUt2lvFpCWl4Jb2zDRbTcSeau9kcEuv7lgqvlV4AYA9O0/4tw32pWFjHpAgklkjS8kvJJ7aO2L4KoDJApaRhvKghVYqBvBdA0Wm/GG2u4LR2s9Jje6tI7hE/tfO0sku5WBiDfJLGkbYBKiTcyjYwHimh6Xavqlrr9vp1xERAbqNrO2KNp8KxGMKIvKdWciWFnUcB2ZiojRmltTQ6/YaVPdJ4dWfzkN5bWN7OZYbstEiOkCJ5gdVt0aNMyJmJpCoIUxxgHrw+MPn3axafoMVxBNey21tcNeSLFKqvOqSbxCy4cwHbgn+LOMJ5ka/GWSOznu77wxHaxQSSRz7tZt1NsRI0cfnB9u0sUbIXcRjA3EqD5Xdasz2s13ZXGkteTXNtFEFSaSeQrOspSe3hkeSALsRGEaKS0OzAVosW57rUPC91qE8Oo2EclvJuitLu5kadEdjFLHcXCJtJiFwZTjzJPmL7mDGgD5Eooor9wP5UCiiigAooooA+g/2CP8AksGrf9gCb/0ot6+26+JP2CP+Swat/wBgCb/0ot6+26/MuKf+Rg/RH7t4f/8AInj/AIpBRRRXzh9qFFFFABX58ftef8nEeKP+3T/0khr9B6/Pj9rz/k4jxR/26f8ApJDX6B4bf8jSp/17f/pUT6rhD/fZ/wCF/mjyiiiiv2s/RgooooAKKKKAMWiiiv5UPw8K07H/AI9U/H+dZladj/x6p+P86AJ6KKKALOm/69v93+orQrP03/Xt/u/1FaFABRRRQB9B6vrVtNp9rNpt3caUrxboI3d5fJkljjVY/MRQyusEhRVXzmZS4UQkHaaJou9Z7PVwJr+701IzBNaulxt87dtnlMTrLIQUjjVC+2NRhD1M+j6PaWviW7vI/sOpWt06+TdSXqRrOk0pWZmK7VRmjhUMjNuVwzKqDaU2zYRQ6na+YmnPZW5dXmfhnvEJMk7xsQckSbPJkA2SxwKNqSBXAMVZo9PvI7rQ10+2s2ngszPqbiV55DPIYJnSBcFTCJAGkQgBAo5VhUaLYSR3Cy6YmhWVxiO4sUaWKRYIiZnWJSQJ40yzyMoCgFmEYyC3R6Nc2Wo24W4TT5fDMV4hmitFXz3u5IoY5kDER5YOxVwiRDEig5BkWqultaRaVZ6kul3Fta3FndLJCJHltb6AToPKVBLvXJklACAnD/NGwylAEtxrN/pOtmC3tbqfTr++F3LqEJFzew7ovLEM4mLpiTZGEwfnQqYw24YypYAmuXt7q2navrV7baTZ3E1qztItxamTfMI1eLCIcvGkIAwqtuYgvsS0L6A1tHvBm1e4bztMuVnUalK0hEUxdstFcu8chVnLqrYIb5Ay1Jb57zxTY3Nldf2WI4lSW83/AGdbi+yC7FJJVkBHmOkrLKDmclgrsyuAdHqFxAII7uKVpRLIputT025t5rj7Y7nFtcrErM0SqxAypYLAwCB2BWn4itL4ajpGnaHqGqmFbJr5bie2lLwgKlxASJAPtH+kO5ZmVmQhNwVgzNjarNrU1hCx1/RtVj+0T3TSW+pSgFgx3yYCLHtJEoSUJsURjLjygDX12z0RLuUS20E6yJIlsJbhbe4jjuImEJjkSRgyboJvmdpFEcgY7lCbgDurC2N/a2EF6bu4W9vbpPsFpa+bA6HG6bzEZFkVZHRtis4QhVwTHuXIssPrcsxvo4WlWa4mfTdRngS7Nz5HlBW83B+9GfMZ13NJh1CgzU3Sbq9stbuLe9ttPFutql7dGygCSSNFHFcF/NU7Qrn7LE7/ADQsR5mQXNSXAt7jVBdatBOWFzFfx6lp9osZlVI3bcbhwvnSCSJYYlKDcFWTa5PygHyPRRRX7gfyoFFFFABRRRQB9B/sEf8AJYNW/wCwBN/6UW9fbdfEn7BH/JYNW/7AE3/pRb19t1+ZcU/8jB+iP3bw/wD+RPH/ABSCiiivnD7UKKKKACvz4/a8/wCTiPFH/bp/6SQ1+g9fnx+15/ycR4o/7dP/AEkhr9A8Nv8AkaVP+vb/APSon1XCH++z/wAL/NHlFFFFftZ+jBRRRQAUUUUAYtFFFfyofh4Vp2P/AB6p+P8AOsytOx/49U/H+dAE9FFFAFnTf9e3+7/UVoVn6b/r2/3f6itCgAooooA+mLHVbkXct1JrCQRXEjTXagy7oY5pJAVkblpJl8qFSxKvH5SxxlXZMpPaafq08iXmlBlMTxpdwpAMxjZJhHcsWMg3nAYKr/u921mdKlhLoGsw6ho2l36Rmxjis7RbhXiRInCxi6lY4iknMRMjKoXzFgkBLR7vMg1eX7FDPYrb6dFpFotu0/nxPbxiVQArXKqzGdZYyEl2IHWR9jlcZYA3vF+nWt0moWmnXM2ryW8NtHaRGGOIQb5VEJCJG210LRsPNKbRcvwoytLot9ci9vXvbR/LWziura2tURDpYSFpYlZNybPKMLIkaPG0gR3dBxkbQ7J7i4sJbaK/lhnna0NwVl/fTq0qxeaYSxY+QWd3YuqsBIZI13NnaLqllcRjWYrlrvT9O0+KSTZKiXMec+VG4DKhJiE0hkiHmAEbY1YfMAOurG1s5p7e+u9I1BrB0t7JdduWaE22A0kQ2/NcSma3EKqsZPyiQRgt81TXbLX4Lqe/tbo6TZalZ+bLHBfRNDHLcSyJ9oYxoE+8EUuVXbEwVmGCtaXh25ni1aCy0nw1A9zawT3M9v8AapLdrSC5hjkAidC0s4Iixubc4feAFwoFONLy41UPY6/NZrd3EUvkTZkW3lWOOZj5EIia4lLskZKxH5fLV+SUABJpra9aaxbtb3Nj4pusWsxtJLlrll80GT55PLcAf6xFnMhb91A4YIRG+Zd3erWlhZXui2NzpWnXCiRYLSL7M+pNbsjp9nY537YELL5ikMSceZ8iV0VpHBFDpj6dcXFleabfTWyf2cINQvEWUu8Q8yYElcJInl7VUkEEsynDLrSNNuba7Oo3NzPYiOS4iljtBb381rLlN4Rs+fJM5WLcAudu52MThJAClb6tajUX1bQ59J0TV5l+xXMliIGkndrg75Dgqq4MRWN3WPJfDL5ZLLtXmgve2Srqenaxf2Fvtiumt7iW6Mo8xUYwJvfYcrI2YmDEI25Ssp8uhB4Xu9H0q5t9F1TT5dRxGxuJnnimnkim2B2IZX5coiGIhiLiRfnaM+ZRWDTNK8WTL4Y0+2Oq37kWV21tLcRW8Mr7xIHiJjVJbYJtYjepHIRSSgB8rUUUV+4H8qBRRRQAUUUUAfQf7BH/ACWDVv8AsATf+lFvX23XxJ+wR/yWDVv+wBN/6UW9fbdfmXFP/Iwfoj928P8A/kTx/wAUgooor5w+1CiiigAr8+P2vP8Ak4jxR/26f+kkNfoPX58ftef8nEeKP+3T/wBJIa/QPDb/AJGlT/r2/wD0qJ9Vwh/vs/8AC/zR5RRRRX7WfowUUUUAFFFFAGLRRRX8qH4eFadj/wAeqfj/ADrMrTsf+PVPx/nQBPRRRQBZ03/Xt/u/1FaFZ+m/69v93+orQoAKKKKAPoyODRr27W51iyvrqO12W4soLOdTZztIv7p5JsR2wJ/eSB9zEsSW4Vasz+KLmXwtfRzTQpZazaTWkt1cwyKioTtQmY7R9obfLvViELF2BjyTNf1KTSbyK6giuPEljaNBcyHw/cWkn2hJCLkl2lLM0XmbjERGrMSpJyu9qwbLTbmyll0PVtLHknlYhqkhWwlcKgbbJvkh8yWUzMCRuVclQIf3gBan1C6vLLRb/Wre80vTrT/RpNHige1aNzgq0ZSESmPPn+aE2/6nC/IMm/b3kf2a3FxqLtZ2rrf6cTGsbx2nkJGzhJGVbjcGdN21SCjBcF4MX9I0PV7Pw7dabqtvqKvbwpZRvZ2rSbnUyQqFni2OB5dzEq7w2FDkbmLBc29E9rbQavbOzS65PbzrpxvraKC6WVSZM9VnXzG4MjRuR5p2rtUkAggvJ4PGQVIQb9be2OofZtLknuLPyZZJmRmjdgoe5V1ZSWwqRkE7fMpunQ6w+ste6dBaaVocUsHIt8WZCuyKqrGqXLbfNtULFwJNjA7o1GxbCSK18JtNYvJf2ENqDqkrmYiVDNJKzhZJcoDGs0i/uSwDLncruFs/Ey6k02wtNEvDNqW+Ge7e8uBNZtH5apGhEbuiybisyYDmTbKChwV3gBdz+HLqHUGuvFGsEIxt2hvLN5zNBM7kR+e+1IHlTep/eo7FIw+145Eerr2l3a3OpRaTrEl3Lp1q9nNJfX1wJt6BnlVJV3LlJI3CL8ykxklfkcvUuTcQxxyXlzozw2qKdQ0/zntpLlNkazS3jo/yTRyMyk/MyySMwVWOH3NGs4LvUdIvL9bn7PbfaCkMltNFc3E4dkkDLEu9Ss81626JAkY8vdtLsAARanqd/wCTazPrMTWyxC5skshJai5g85EbzQsYGI2XLMkauAyyLtCBWdYPp5v9VtV1aea3t7oNDm2S9aSZnkhWWWPzAhbzXSSONF82RY9rByFNZWnxpbawttp8n2XSNau0bT2Fo0kqsgaaF0jRSmClyQfMkdH8wbgv7xY4tQ1C68R6jp9jJeRwWsaWtzp02n2/P2JIpVKyJFIAhKbk8mP94A7hRhcOAf/Z/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCADwAUADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD6rooooAKKKKACqGuf8ei/9dB/I1fqhrn/AB6L/wBdB/I187xZ/wAibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/5CUf/AFxH82rqK5fxb/yEo/8AriP5tX6X4S/8lFH/AAS/I/PvE3/kRS/xRMeiiiv6lP5wCiiigArnLv8A4+5v+ujfzNdHXOXf/H3N/wBdG/ma/MPE/wD3Sh/if5HZgviZFRRRX42eiFFFFAFDxD/yBp/+A/8AoQrkK6/xD/yBp/8AgP8A6EK5Cv6U8G/+RHV/6+y/9Igf154Af8k5X/6/S/8ASKYUUUV+sH7gFFFFAGXr3/LH/gX9Ky61Ne/5Y/8AAv6Vl1/PPHX/ACPq/wD27/6RE9bDfwkFFFFfJG4UUUUAcf4i/wCQzP8A8B/9BFZ9aHiL/kMz/wDAf/QRWfX9pcK/8iPBf9eqf/pCP5J4k/5HGL/6+T/9KYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/49F/66D+Rr53iz/kTYj/AAmtD+IjGooor+bj2AooooAK5fxb/wAhKP8A64j+bV1Fcv4t/wCQlH/1xH82r9L8Jf8Akoo/4Jfkfn3ib/yIpf4omPRRRX9Sn84BRRRQAVzl3/x9zf8AXRv5mujrnLv/AI+5v+ujfzNfmHif/ulD/E/yOzBfEyKiiivxs9EKKKKAKHiH/kDT/wDAf/QhXIV1/iH/AJA0/wDwH/0IVyFf0p4N/wDIjq/9fZf+kQP688AP+Scr/wDX6X/pFMKKKK/WD9wCiiigDL17/lj/AMC/pWXWpr3/ACx/4F/Ssuv5546/5H1f/t3/ANIiethv4SCiiivkjcKKKKAOP8Rf8hmf/gP/AKCKz60PEX/IZn/4D/6CKz6/tLhX/kR4L/r1T/8ASEfyTxJ/yOMX/wBfJ/8ApTCiiivePFCiiigD9NqKKK/kw90KKKKACqGuf8ei/wDXQfyNX6oa5/x6L/10H8jXzvFn/ImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/1xH82rqK5fxb/yEo/+uI/m1fpfhL/yUUf8EvyPz7xN/wCRFL/FEx6KKK/qU/nAKKKKACucu/8Aj7m/66N/M10dc5d/8fc3/XRv5mvzDxP/AN0of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/wDIGn/4D/6EK5Cuv8Q/8gaf/gP/AKEK5Cv6U8G/+RHV/wCvsv8A0iB/XngB/wAk5X/6/S/9IphRRRX6wfuAUUUUAZevf8sf+Bf0rLrU17/lj/wL+lZdfzzx1/yPq/8A27/6RE9bDfwkFFFFfJG4UUUUAcf4i/5DM/8AwH/0EVn1oeIv+QzP/wAB/wDQRWfX9pcK/wDIjwX/AF6p/wDpCP5J4k/5HGL/AOvk/wD0phRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP+PRf+ug/kav1Q1z/AI9F/wCug/ka+d4s/wCRNiP8JrQ/iIxqKKK/m49gKKKKACuX8W/8hKP/AK4j+bV1Fcv4t/5CUf8A1xH82r9L8Jf+Sij/AIJfkfn3ib/yIpf4omPRRRX9Sn84BRRRQAVzl3/x9zf9dG/ma6Oucu/+Pub/AK6N/M1+YeJ/+6UP8T/I7MF8TIqKKK/Gz0QooooAoeIf+QNP/wAB/wDQhXIV1/iH/kDT/wDAf/QhXIV/Sng3/wAiOr/19l/6RA/rzwA/5Jyv/wBfpf8ApFMKKKK/WD9wCiiigDL17/lj/wAC/pWXWpr3/LH/AIF/Ssuv5546/wCR9X/7d/8ASInrYb+Egooor5I3CiiigDj/ABF/yGZ/+A/+gis+tDxF/wAhmf8A4D/6CKz6/tLhX/kR4L/r1T/9IR/JPEn/ACOMX/18n/6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/AB6L/wBdB/I1fqhrn/Hov/XQfyNfO8Wf8ibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/wCQlH/1xH82rqK5fxb/AMhKP/riP5tX6X4S/wDJRR/wS/I/PvE3/kRS/wAUTHooor+pT+cAooooAK5y7/4+5v8Aro38zXR1zl3/AMfc3/XRv5mvzDxP/wB0of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8AIGn/AOA/+hCuQrr/ABD/AMgaf/gP/oQrkK/pTwb/AORHV/6+y/8ASIH9eeAH/JOV/wDr9L/0imFFFFfrB+4BRRRQBl69/wAsf+Bf0rLrU17/AJY/8C/pWXX888df8j6v/wBu/wDpET1sN/CQUUUV8kbhRRRQBx/iL/kMz/8AAf8A0EVn1oeIv+QzP/wH/wBBFZ9f2lwr/wAiPBf9eqf/AKQj+SeJP+Rxi/8Ar5P/ANKYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/49F/66D+Rr53iz/kTYj/Ca0P4iMaiiiv5uPYCiiigArl/Fv/ISj/64j+bV1Fcv4t/5CUf/AFxH82r9L8Jf+Sij/gl+R+feJv8AyIpf4omPRRRX9Sn84BRRRQAVzl3/AMfc3/XRv5mujrnLv/j7m/66N/M1+YeJ/wDulD/E/wAjswXxMiooor8bPRCiiigCh4h/5A0//Af/AEIVyFdf4h/5A0//AAH/ANCFchX9KeDf/Ijq/wDX2X/pED+vPAD/AJJyv/1+l/6RTCiiiv1g/cAooooAy9e/5Y/8C/pWXWpr3/LH/gX9Ky6/nnjr/kfV/wDt3/0iJ62G/hIKKKK+SNwooooA4/xF/wAhmf8A4D/6CKz60PEX/IZn/wCA/wDoIrPr+0uFf+RHgv8Ar1T/APSEfyTxJ/yOMX/18n/6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/Hov/XQfyNX6oa5/x6L/ANdB/I187xZ/yJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/kJR/wDXEfzauorl/Fv/ACEo/wDriP5tX6X4S/8AJRR/wS/I/PvE3/kRS/xRMeiiiv6lP5wCiiigArnLv/j7m/66N/M10dc5d/8AH3N/10b+Zr8w8T/90of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8gaf/AID/AOhCuQrr/EP/ACBp/wDgP/oQrkK/pTwb/wCRHV/6+y/9Igf154Af8k5X/wCv0v8A0imFFFFfrB+4BRRRQBl69/yx/wCBf0rLrU17/lj/AMC/pWXX888df8j6v/27/wCkRPWw38JBRRRXyRuFFFFAHH+Iv+QzP/wH/wBBFZ9aHiL/AJDM/wDwH/0EVn1/aXCv/IjwX/Xqn/6Qj+SeJP8AkcYv/r5P/wBKYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/AI9F/wCug/kav1Q1z/j0X/roP5GvneLP+RNiP8JrQ/iIxqKKK/m49gKKKKACuX8W/wDISj/64j+bV1Fcv4t/5CUf/XEfzav0vwl/5KKP+CX5H594m/8AIil/iiY9FFFf1KfzgFFFFABXOXf/AB9zf9dG/ma6Oucu/wDj7m/66N/M1+YeJ/8AulD/ABP8jswXxMiooor8bPRCiiigCh4h/wCQNP8A8B/9CFchXX+If+QNP/wH/wBCFchX9KeDf/Ijq/8AX2X/AKRA/rzwA/5Jyv8A9fpf+kUwooor9YP3AKKKKAMvXv8Alj/wL+lZdamvf8sf+Bf0rLr+eeOv+R9X/wC3f/SInrYb+Egooor5I3CiiigDj/EX/IZn/wCA/wDoIrPrQ8Rf8hmf/gP/AKCKz6/tLhX/AJEeC/69U/8A0hH8k8Sf8jjF/wDXyf8A6Uwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/Hov/XQfyNX6oa5/wAei/8AXQfyNfO8Wf8AImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/wBcR/Nq6iuX8W/8hKP/AK4j+bV+l+Ev/JRR/wAEvyPz7xN/5EUv8UTHooor+pT+cAooooAK5y7/AOPub/ro38zXR1zl3/x9zf8AXRv5mvzDxP8A90of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8gaf/gP/AKEK5Cuv8Q/8gaf/AID/AOhCuQr+lPBv/kR1f+vsv/SIH9eeAH/JOV/+v0v/AEimFFFFfrB+4BRRRQBl69/yx/4F/SsutTXv+WP/AAL+lZdfzzx1/wAj6v8A9u/+kRPWw38JBRRRXyRuFFFFAHH+Iv8AkMz/APAf/QRWfWh4i/5DM/8AwH/0EVn1/aXCv/IjwX/Xqn/6Qj+SeJP+Rxi/+vk//SmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/49F/66D+Rq/VDXP+PRf+ug/ka+d4s/5E2I/wAJrQ/iIxqKKK/m49gKKKKACuX8W/8AISj/AOuI/m1dRXL+Lf8AkJR/9cR/Nq/S/CX/AJKKP+CX5H594m/8iKX+KJj0UUV/Up/OAUUUUAFc5d/8fc3/AF0b+Zro65y7/wCPub/ro38zX5h4n/7pQ/xP8jswXxMiooor8bPRCiiigCh4h/5A0/8AwH/0IVyFdf4h/wCQNP8A8B/9CFchX9KeDf8AyI6v/X2X/pED+vPAD/knK/8A1+l/6RTCiiiv1g/cAooooAy9e/5Y/wDAv6Vl1qa9/wAsf+Bf0rLr+eeOv+R9X/7d/wDSInrYb+Egooor5I3CiiigDj/EX/IZn/4D/wCgis+tDxF/yGZ/+A/+gis+v7S4V/5EeC/69U//AEhH8k8Sf8jjF/8AXyf/AKUwooor3jxQooooAKKKKACiiigAqhrn/Hov/XQfyNX6oa5/x6L/ANdB/I189xZ/yJsR/hNqH8RGNRRRX82nrhRRRQAV618Gf+RXuf8Ar9b/ANASvJa9a+DP/Ir3P/X63/oCV9Lwn/yMV6M+v4H/AORqv8LO2ooor9RP2cKKKKACvAfFX/Iz6r/1+zf+htXv1eA+Kv8AkZ9V/wCv2b/0Nq+M40/gUvV/kfn3iF/u1H/E/wAjNooor88PyoKKKKAO9/Z6/wCSwaH/ANvH/pPJX1zXyN+z1/yWDQ/+3j/0nkr65r6bJf4D9f0R+H+Jf/I1p/8AXtf+lTCiiivXPzwKKKKAPBP2u/8AmWP+3v8A9o14JXvf7Xf/ADLH/b3/AO0a8Er5HM/96n8vyR/Q3Av/ACIaH/b3/pcgooorgPrQooooA/Qf9kL/AJN28Mf9vf8A6VzV6vXlH7IX/Ju3hj/t7/8ASuavV6ACiiigAooooA/LX+1/+nf/AMf/APrUf2v/ANO//j//ANasuiv6B/tbF/z/AIL/ACP53/1uzj/n9/5LH/I1P7X/AOnf/wAf/wDrUf2v/wBO/wD4/wD/AFqy6KP7Wxf8/wCC/wAg/wBbs4/5/f8Aksf8jU/tf/p3/wDH/wD61V76++0wiPytmGzndn19qp0VzYvF1sZRlQrO8ZaNaL8tSo8YZxF3Vb/yWP8A8ieg/AT4af8AC0vGF34f/tr+yPs+nveef9l8/dtkjTbt3rj/AFmc57dOa9u/4Y3/AOqi/wDlE/8At9cn+wR/yWDVv+wBN/6UW9fbdfkOf4SjhMY6dFWjZd3+Z+vcH5jicxy1V8TLmldq9ktvRJHyh/wxv/1UX/yif/b6P+GN/wDqov8A5RP/ALfX1fRXin1B8of8Mb/9VF/8on/2+ut8Gfs1f8I7pctl/wAJn9q3zGXf/ZezGVUYx5p/u/rX0FRXThMZWwdT2tF2l8n+Z2YHH4jAVfbYeXLLa9k/zueMf8KJ/wCpp/8AKf8A/bK+fPi94g/4QD4iap4R+yf2l9g8r/SfM8rzN8KSfcw2Mb8dT0zX3VX58ftef8nEeKP+3T/0khr9F4JzHE5nj50cVLmioN2slreK6Jd2fc8N8R5ljcVKnXqXSi3tFa3XZFD/AIWl/wBQP/yb/wDsKP8AhaX/AFA//Jv/AOwrzeiv1D+zsN/L+L/zPtfrlb+b8j0j/haX/UD/APJv/wCwrgNVuvt2qXd75fl/aJnl2Zzt3MTjPfrVaiuLG8O5djoqNendLzkvyaPOzDDUsxio4lcyW3T8rBRRRXnf6kZH/wA+P/Jp/wDyR5X+reWf8+/xl/mUvt//AEy/8e/+tR9v/wCmX/j3/wBaqVFfz+flZ1nw98Zf8In4wsfEH9nfbfsvmfufP8vdujZPvbTjG7PTtXs0H7SHmxB/+ENxnt/af/2qvm2tOx/49U/H+ddVHGVqEeWnKy+R4eZ8N5ZmlVVsXT5pJWveS0u30a7s+gv+Gjf+pO/8qf8A9qo/4aN/6k7/AMqf/wBqrwSitf7UxX834L/I87/UXIf+fH/k0/8A5I+gLb9ofznK/wDCIbcDP/ISz/7Sqx/wv7/qU/8Ayo//AGuvANN/17f7v9RWhR/amK/m/Bf5B/qLkP8Az4/8mn/8kdj8XvHH/Cf/ANl/8Sz+zfsHnf8ALfzd/mbP9lcY2e/WuC+wf9Nf/Hf/AK9XKK5KtWdWTnN3bPosBgaGAoRw+Hjywjeyu3u7vV3e7O91D4M3VlNNHNqdyoYFLJ/sSFJbhlQxW8jLKRDISzqwYnBVQvmbjtsaZ8GrC+1SHTx4ukhkdHd/N05EKbWYBSrTAqxXynBcKhRyQ5wA3qmjodNvW8PX2nataq6s2oxWn+kQHzAJG8qIO064eGPEqAtGd+QpIVK1jpd5caRFc2GnR29pqd/cI959mmuptQgeCRMyIpby/NWVmZoxtYujfu1Rd+Z1nl9p8GDe6drVzZeJYXbT2ja3eS2EdvcwzOywSeaZPkDbHzlSqkAFj8xSGz+D897fxmxvdXuNLkDyC6GkbZBCnk7pCjShePMfKhy3yLxiRa9svo9UvdUeLWNK02VL53uF0m8byYLa9macs2Y0H2liqxK4BfmSYABDis/+zLnT/ECSWHm289hfRW0Udw86GAXTq8cbJE7CbEJcEhkZhHGFCsUEgB2Hwb8ZweBvB2j/AA+i0LV9UvLK9ns3fdaws0jTzSMAvnMDsUPuIYqCoG7JIHW6X8XTf32nRx+HGa1vhPsuEv0ONlx5KcMF3BshwVLZAfZ5hXB8glMum+FLy4sobbUb23slZYri9dbpXdhcFpNkjxvGZN2I2ZX+UspZiZHunW9QsdTtZVgvpfK1A6dai0eJWtrx0AlaSadP9IYrlleQKjsoGWBJAB6YnxmMdhbajf8Ahh7Oxvb+Cys5m1CM+cZnG1unRU3M4ySpAHIIetLTviZc3U0FvL4bktbm9Sc2ME07pJK8SsWR1aIGMg+WCOSd+5Q6DcfGo0TTfBImOkixfWIJ7c2FwftAlKxsWYxpGkgYtAu6VHVd21/vbVRmo+FIYLHQrmSO8mktbXzLdbedhLfsixASbJATbs0axxylshWWJF4dVYA9Rv8A4yX8MlzaW/g8TX0CZ8t9QMUbbPME7l2i+SJHj8vzGADOyjgENWxYfEyS7WFI9L0+WeWSSFY4tU/1kg8sxJH5kSGQvG7yZAwBH1yePH9Fk010m17Tr2xjkuZ5wyROyRRIyPF9seJnKwDejyHf5zeWuxThWjWbQNY0bSL6O7n1SDy726a4fEkzSWqyeTJJG5Y7trKiEMR5ZSEM3lbgaAPkCiiiv3A/lQKKKKACiiigD6D/AGCP+Swat/2AJv8A0ot6+26+JP2CP+Swat/2AJv/AEot6+26/MuKf+Rg/RH7t4f/APInj/ikFFFFfOH2oUUUUAFfnx+15/ycR4o/7dP/AEkhr9B6/Pj9rz/k4jxR/wBun/pJDX6B4bf8jSp/17f/AKVE+q4Q/wB9n/hf5o8oooor9rP0YKKKKACiiigDFooor+VD8PCtOx/49U/H+dZladj/AMeqfj/OgCeiiigCzpv+vb/d/qK0Kz9N/wBe3+7/AFFaFABRRRQB9OW+t389pdXOiv5+q6zdRiF47yT7MqLaskSRylRsZpBAj+YQwZxjYWDLcu7Ky0nwTq2jwXM8zXmoxWspmtokgkUziPEEYXCnYiOyorxiM/cz8oZaXtidI0q00xrRf7C06S5u7i5a6ikWHy9s2zyojLEsUlu+ZGwQY4kBxIpFW2kjtNE0iKTw9ot1b3qRWGnGWKNpcpvzMeJPN2P9+MM2ZdmNxdUYApPrKa7c6t5F1qljaJ59tcXMWnRPEtqQqy2ySuqSMEVhvByyhU+VlTzKNOtPEoFjBrWn+fYXVjss4Unjh026g2GeHaEiSEMNg3NJglpNwXbFsqbT5tZ028n1/U4YNUtmvbgWFxdxyCKF43Dq6XUMZLxsSdo8obwpRSIziRLew0jUdNj8QT3/AMlvDEiJ9j/sqRzI5ALvITHIWEBVcMMCMB32BnIBlTy6br95Kt9qcY0qOSRYYJIkV7NDOQgliIlYN5zRxsioWYESO20ESburaJqWmy3Xh8Wbw6Rc2l3AXEH2g28C43ymBC4jVpZGlDjJAfp95RT0zQ5bGfT9Q1eYxz6RPdSwa4ZXSO6YQSOVAVHkIOwmRj8gbzQfMZcNpWN3PpUaXOp22v28dvMJrSVpoXubp/3MXnyzxMUBVIpGxOfKdsqznyywADRfEE1ysd3eRBWvrQWjzxW5uVsogAi2cgV8xvIGLqgfzFdwF3lnQUZNFh8K67DdpqOpW9nJEJrtbW8YzW5YPIDGEKqYYhHIT+73qrO3lg+XsxLK0n0bVAbnUR/at/fyxT6gks6pbTlSjTP5bK0UcjyRMEkQjoSFWQAdzpdvK1lq40jX7BbS+lgkiUTQhbIrA0jvukjXCstvC6eWo2rgxhVBkABzfjTVIn8OWr3+nvp+kLFKyOLQ+VDcBZIdrQuDtbMaBU3lVjjMQRfv1N4bsNXsbg3vhrWhLGE3x2VtNczGxBZnnkbKwsVCyEp5qys4Crtm2oVv63ctplpEmpalY3kcPkC4TUTHvRXnaeD7M8jLGA5VmYMNuLdFMZ+WMwxPe3WkxwyRy6+0l/PEXkVgsMJYL5rMR5jqJ40kYYkTMmxFYigD5Kooor9wP5UCiiigAooooA+g/wBgj/ksGrf9gCb/ANKLevtuviT9gj/ksGrf9gCb/wBKLevtuvzLin/kYP0R+7eH/wDyJ4/4pBRRRXzh9qFFFFABX58ftef8nEeKP+3T/wBJIa/Qevz4/a8/5OI8Uf8Abp/6SQ1+geG3/I0qf9e3/wClRPquEP8AfZ/4X+aPKKKKK/az9GCiiigAooooAxaKKK/lQ/DwrTsf+PVPx/nWZWnY/wDHqn4/zoAnooooAs6b/r2/3f6itCs/Tf8AXt/u/wBRWhQAUUUUAfQlzfPcSadc3kE1nqNnbNJZ31rFboRMUaN2lJZERS0cCp5ZZ2hibLFmUiWy0u6TXtNhudbjiaS3EkGpWEOSbeULb7WEaukatx++5CiKAbYC5zPqlzqNlbvqE1lNfX+pv9p/tbTxHCIEldYvs6kb90eYwBIxZsFYAFy+2Hw3qGiaxq6f2cZ7fULuyt7O3fVJLW3gMLRKUiaI7lhSY7z5cR3gLuiASV/LALevR2kNteRa9qNzJaJqTXMGnLp/nQWpjlkwzvNFJ50rOBGY1YKxdgXZdzLaTSrvw1p+iataS2kQVjNfeVEJF1FUDzlpXgAUJGAykxxtHlwzOzjaIJvEWoDwMdX0zU7JTa2d3Cl3cQu8tm5EbLaIpkRldWDCNnR34UgLHkizq+vaZd6vb3Pnadqt+6Xccmo292sRsGIExkVI2WafYiqC0LAAbwpbmNQCe4ksrjwQmqaklha3l4Untb2LTTFK5iDiOXEavJENigbgSU8w+UNyqa5/xUniKS5gnhubJZrm6FmUupkVkZkiE8axlDOjM86pmNlbc0km0bjNV7WtF0TS5G8T6hDOsup+akVpdQR28SkmaR1BDBDlnASRhtDgudu6IUeItO1Kzt47C3ksrGPSp4xJpun/ACxxGS4keGSSQRnzFBhQCZ9jrjlX83EoBO090vhi50q+0fTnlcCzu764AjtpJJdscN0JxCgMaeYqEAblEYUYwVnqz+HwmnR6ldyalJpUF+1vM17ZypDp8flglnSVnl2KPLCLIxUsUOAqnzDw7rSa9rX9jvpt14fuLFTBd3Fmnn28csUrtC4im+WMZjlVBh2Ee6PZtVXTQ1jQbzTNBWRLjV3uY0bzHhlkW8s2Frazqm/5TLcALgbcDEmCvyAKAc9p+r3dr4p0qwmm8N3a6Pb29mn9raUkUSpHHG7LHIYg44BkUngjDZUusRks2ufseoXMtnDoktvpzXem28EMiXNrcqknl73kQlEZoJU+VlBESh2bzmZt6w/sRPEWn2GpXL2ct1I8UupXlqRBcPB+5KxuEwqj7OvytKNpAwW3FqzdPMLeFZNaupAWuoE+yS3TQw7rlUJi+0KvkiNP3kSo4YAblJZlWJ2APlSiiiv3A/lQKKKKACiiigD6D/YI/wCSwat/2AJv/Si3r7br4k/YI/5LBq3/AGAJv/Si3r7br8y4p/5GD9Efu3h//wAieP8AikFFFFfOH2oUUUUAFfnx+15/ycR4o/7dP/SSGv0Hr8+P2vP+TiPFH/bp/wCkkNfoHht/yNKn/Xt/+lRPquEP99n/AIX+aPKKKKK/az9GCiiigAooooAxaKKK/lQ/DwrTsf8Aj1T8f51mVp2P/Hqn4/zoAnooooAs6b/r2/3f6itCs/Tf9e3+7/UVoUAFFFFAH06Lm61aKVrG18ifUpElhiv7QpDqU7tvd5IFO5442OFl2hn3LGyyssiy39chvoYGj1V20pZNRfSpphCvlPG8UfmNKskSwyoZX3BsoVLNkOQwOHd241TS0sdRt4rK5sZBYo1vqUNrO8KM6pAsxKxCRXRHyFAkaDnGVCyW6Wn/AAiFto9hfxiW2+0SwX94DOjQy4jkQRZCSIFCYkCNDMwkII5JAGX82nXynXp7jTdXn1UuRp1lb3SpeNtkX93sKhnMsELKVUEKgd9zBa09G1C/u/Dl3ZTaDDY3tsk+li1mjjmg2JIi+b5bQ4dUxs3x+aiBz8hDLGMvxJqml2XjHU11qO51G9adQ9/bThrZ4Zptkq8fvFUIz+WMsFZI0Xc0ZeSw0mmHT9R1aTydWjlR7a70+NlYxNGEklnmaJsGH7VE0hEYUMHIDv8ALEADNn0HWhp/2+XQDfLLpL3MVvdswbyYbjbDG9vO0m3y4tzIQuW3KuMiYSaGl6jJr3iC8aZ7nUL0x2stu0Hl/arl3UDykEiqgSJhIxKhV8xITsYAKa0Nvm/1XWZ9Aa6HFpLZT3QWFYHjhIWLyYy0MZV2wX2u3mozCR1YHI1Ke5a3l1CbVNZN7eysk5gcXlz5U8Dqy7IpAkWWtrkhEGACBIQEUsAbOoXeijQdMhk1aXQ5btWWQwabFbpKX2xRCRGKhYOXVyFCrld2M7peg1Kx0XV9aTWtJmsNRjv7qW7s7fUbS4uoo2KGG4whZfL3lCVU4HmRooxmPFLUJIrC0h8ZQWkvhK5m0h7K3gFxC7GTzkZ2AbEUcSuYgf3cYLyvuxvWWs7wlb6lqMtq+kW0d7e6ZGiWy26QGJfNYysFfmCAgI8zbW8wGRQr4YpGATeGdRW00eONmuL+91naHube4W4SZorh5JEkKDYYmViHCkyJ5zhiwk30/ZbXEmuXlvpcqXCyRiMrZtbz3Jhiy6RzJKhTzIcuEVl3JED92RQd3w1oMMenS2Wi63r1vbC5WF3mlKSIbWSVRFCY2dnbzipAznyiF3EY3cVNpeg2eo6RqnhrUtOgksXF1FqFzM9vHcrO0jRpKPL8zJ+zygIqN5m9SrRgxKwB/9n/2P/gABBKRklGAAEBAAABAAEAAP/bAEMABQMEBAQDBQQEBAUFBQYHDAgHBwcHDwsLCQwRDxISEQ8RERMWHBcTFBoVEREYIRgaHR0fHx8TFyIkIh4kHB4fHv/bAEMBBQUFBwYHDggIDh4UERQeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHv/AABEIAPABQAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APquiiigAooooAKoa5/x6L/10H8jV+qGuf8AHov/AF0H8jXzvFn/ACJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/kJR/8AXEfzauorl/Fv/ISj/wCuI/m1fpfhL/yUUf8ABL8j8+8Tf+RFL/FEx6KKK/qU/nAKKKKACucu/wDj7m/66N/M10dc5d/8fc3/AF0b+Zr8w8T/APdKH+J/kdmC+JkVFFFfjZ6IUUUUAUPEP/IGn/4D/wChCuQrr/EP/IGn/wCA/wDoQrkK/pTwb/5EdX/r7L/0iB/XngB/yTlf/r9L/wBIphRRRX6wfuAUUUUAZevf8sf+Bf0rLrU17/lj/wAC/pWXX888df8AI+r/APbv/pET1sN/CQUUUV8kbhRRRQBx/iL/AJDM/wDwH/0EVn1oeIv+QzP/AMB/9BFZ9f2lwr/yI8F/16p/+kI/kniT/kcYv/r5P/0phRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP+PRf+ug/kav1Q1z/j0X/roP5GvneLP+RNiP8ACa0P4iMaiiiv5uPYCiiigArl/Fv/ACEo/wDriP5tXUVy/i3/AJCUf/XEfzav0vwl/wCSij/gl+R+feJv/Iil/iiY9FFFf1KfzgFFFFABXOXf/H3N/wBdG/ma6Oucu/8Aj7m/66N/M1+YeJ/+6UP8T/I7MF8TIqKKK/Gz0QooooAoeIf+QNP/AMB/9CFchXX+If8AkDT/APAf/QhXIV/Sng3/AMiOr/19l/6RA/rzwA/5Jyv/ANfpf+kUwooor9YP3AKKKKAMvXv+WP8AwL+lZdamvf8ALH/gX9Ky6/nnjr/kfV/+3f8A0iJ62G/hIKKKK+SNwooooA4/xF/yGZ/+A/8AoIrPrQ8Rf8hmf/gP/oIrPr+0uFf+RHgv+vVP/wBIR/JPEn/I4xf/AF8n/wClMKKKK948UKKKKAP02ooor+TD3QooooAKoa5/x6L/ANdB/I1fqhrn/Hov/XQfyNfO8Wf8ibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/5CUf/XEfzauorl/Fv/ISj/64j+bV+l+Ev/JRR/wS/I/PvE3/AJEUv8UTHooor+pT+cAooooAK5y7/wCPub/ro38zXR1zl3/x9zf9dG/ma/MPE/8A3Sh/if5HZgviZFRRRX42eiFFFFAFDxD/AMgaf/gP/oQrkK6/xD/yBp/+A/8AoQrkK/pTwb/5EdX/AK+y/wDSIH9eeAH/ACTlf/r9L/0imFFFFfrB+4BRRRQBl69/yx/4F/SsutTXv+WP/Av6Vl1/PPHX/I+r/wDbv/pET1sN/CQUUUV8kbhRRRQBx/iL/kMz/wDAf/QRWfWh4i/5DM//AAH/ANBFZ9f2lwr/AMiPBf8AXqn/AOkI/kniT/kcYv8A6+T/APSmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/49F/66D+Rq/VDXP8Aj0X/AK6D+Rr53iz/AJE2I/wmtD+IjGooor+bj2AooooAK5fxb/yEo/8AriP5tXUVy/i3/kJR/wDXEfzav0vwl/5KKP8Agl+R+feJv/Iil/iiY9FFFf1KfzgFFFFABXOXf/H3N/10b+Zro65y7/4+5v8Aro38zX5h4n/7pQ/xP8jswXxMiooor8bPRCiiigCh4h/5A0//AAH/ANCFchXX+If+QNP/AMB/9CFchX9KeDf/ACI6v/X2X/pED+vPAD/knK//AF+l/wCkUwooor9YP3AKKKKAMvXv+WP/AAL+lZdamvf8sf8AgX9Ky6/nnjr/AJH1f/t3/wBIiethv4SCiiivkjcKKKKAOP8AEX/IZn/4D/6CKz60PEX/ACGZ/wDgP/oIrPr+0uFf+RHgv+vVP/0hH8k8Sf8AI4xf/Xyf/pTCiiivePFCiiigD9NqKKK/kw90KKKKACqGuf8AHov/AF0H8jV+qGuf8ei/9dB/I187xZ/yJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/AJCUf/XEfzauorl/Fv8AyEo/+uI/m1fpfhL/AMlFH/BL8j8+8Tf+RFL/ABRMeiiiv6lP5wCiiigArnLv/j7m/wCujfzNdHXOXf8Ax9zf9dG/ma/MPE//AHSh/if5HZgviZFRRRX42eiFFFFAFDxD/wAgaf8A4D/6EK5Cuv8AEP8AyBp/+A/+hCuQr+lPBv8A5EdX/r7L/wBIgf154Af8k5X/AOv0v/SKYUUUV+sH7gFFFFAGXr3/ACx/4F/SsutTXv8Alj/wL+lZdfzzx1/yPq//AG7/AOkRPWw38JBRRRXyRuFFFFAHH+Iv+QzP/wAB/wDQRWfWh4i/5DM//Af/AEEVn1/aXCv/ACI8F/16p/8ApCP5J4k/5HGL/wCvk/8A0phRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP+PRf+ug/kav1Q1z/j0X/roP5GvneLP+RNiP8JrQ/iIxqKKK/m49gKKKKACuX8W/8hKP/riP5tXUVy/i3/kJR/8AXEfzav0vwl/5KKP+CX5H594m/wDIil/iiY9FFFf1KfzgFFFFABXOXf8Ax9zf9dG/ma6Oucu/+Pub/ro38zX5h4n/AO6UP8T/ACOzBfEyKiiivxs9EKKKKAKHiH/kDT/8B/8AQhXIV1/iH/kDT/8AAf8A0IVyFf0p4N/8iOr/ANfZf+kQP688AP8AknK//X6X/pFMKKKK/WD9wCiiigDL17/lj/wL+lZdamvf8sf+Bf0rLr+eeOv+R9X/AO3f/SInrYb+Egooor5I3CiiigDj/EX/ACGZ/wDgP/oIrPrQ8Rf8hmf/AID/AOgis+v7S4V/5EeC/wCvVP8A9IR/JPEn/I4xf/Xyf/pTCiiivePFCiiigD9NqKKK/kw90KKKKACqGuf8ei/9dB/I1fqhrn/Hov8A10H8jXzvFn/ImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/ANcR/Nq6iuX8W/8AISj/AOuI/m1fpfhL/wAlFH/BL8j8+8Tf+RFL/FEx6KKK/qU/nAKKKKACucu/+Pub/ro38zXR1zl3/wAfc3/XRv5mvzDxP/3Sh/if5HZgviZFRRRX42eiFFFFAFDxD/yBp/8AgP8A6EK5Cuv8Q/8AIGn/AOA/+hCuQr+lPBv/AJEdX/r7L/0iB/XngB/yTlf/AK/S/wDSKYUUUV+sH7gFFFFAGXr3/LH/AIF/SsutTXv+WP8AwL+lZdfzzx1/yPq//bv/AKRE9bDfwkFFFFfJG4UUUUAcf4i/5DM//Af/AEEVn1oeIv8AkMz/APAf/QRWfX9pcK/8iPBf9eqf/pCP5J4k/wCRxi/+vk//AEphRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP8Aj0X/AK6D+Rq/VDXP+PRf+ug/ka+d4s/5E2I/wmtD+IjGooor+bj2AooooAK5fxb/AMhKP/riP5tXUVy/i3/kJR/9cR/Nq/S/CX/koo/4Jfkfn3ib/wAiKX+KJj0UUV/Up/OAUUUUAFc5d/8AH3N/10b+Zro65y7/AOPub/ro38zX5h4n/wC6UP8AE/yOzBfEyKiiivxs9EKKKKAKHiH/AJA0/wDwH/0IVyFdf4h/5A0//Af/AEIVyFf0p4N/8iOr/wBfZf8ApED+vPAD/knK/wD1+l/6RTCiiiv1g/cAooooAy9e/wCWP/Av6Vl1qa9/yx/4F/Ssuv5546/5H1f/ALd/9Iiethv4SCiiivkjcKKKKAOP8Rf8hmf/AID/AOgis+tDxF/yGZ/+A/8AoIrPr+0uFf8AkR4L/r1T/wDSEfyTxJ/yOMX/ANfJ/wDpTCiiivePFCiiigD9NqKKK/kw90KKKKACqGuf8ei/9dB/I1fqhrn/AB6L/wBdB/I187xZ/wAibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/5CUf/AFxH82rqK5fxb/yEo/8AriP5tX6X4S/8lFH/AAS/I/PvE3/kRS/xRMeiiiv6lP5wCiiigArnLv8A4+5v+ujfzNdHXOXf/H3N/wBdG/ma/MPE/wD3Sh/if5HZgviZFRRRX42eiFFFFAFDxD/yBp/+A/8AoQrkK6/xD/yBp/8AgP8A6EK5Cv6U8G/+RHV/6+y/9Igf154Af8k5X/6/S/8ASKYUUUV+sH7gFFFFAGXr3/LH/gX9Ky61Ne/5Y/8AAv6Vl1/PPHX/ACPq/wD27/6RE9bDfwkFFFFfJG4UUUUAcf4i/wCQzP8A8B/9BFZ9aHiL/kMz/wDAf/QRWfX9pcK/8iPBf9eqf/pCP5J4k/5HGL/6+T/9KYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/49F/66D+Rr53iz/kTYj/AAmtD+IjGooor+bj2AooooAK5fxb/wAhKP8A64j+bV1Fcv4t/wCQlH/1xH82r9L8Jf8Akoo/4Jfkfn3ib/yIpf4omPRRRX9Sn84BRRRQAVzl3/x9zf8AXRv5mujrnLv/AI+5v+ujfzNfmHif/ulD/E/yOzBfEyKiiivxs9EKKKKAKHiH/kDT/wDAf/QhXIV1/iH/AJA0/wDwH/0IVyFf0p4N/wDIjq/9fZf+kQP688AP+Scr/wDX6X/pFMKKKK/WD9wCiiigDL17/lj/AMC/pWXWpr3/ACx/4F/Ssuv5546/5H1f/t3/ANIiethv4SCiiivkjcKKKKAOP8Rf8hmf/gP/AKCKz60PEX/IZn/4D/6CKz6/tLhX/kR4L/r1T/8ASEfyTxJ/yOMX/wBfJ/8ApTCiiivePFCiiigAooooAKKKKACqGuf8ei/9dB/I1fqhrn/Hov8A10H8jXz3Fn/ImxH+E2ofxEY1FFFfzaeuFFFFABXrXwZ/5Fe5/wCv1v8A0BK8lr1r4M/8ivc/9frf+gJX0vCf/IxXoz6/gf8A5Gq/ws7aiiiv1E/ZwooooAK8B8Vf8jPqv/X7N/6G1e/V4D4q/wCRn1X/AK/Zv/Q2r4zjT+BS9X+R+feIX+7Uf8T/ACM2iiivzw/KgooooA739nr/AJLBof8A28f+k8lfXNfI37PX/JYND/7eP/SeSvrmvpsl/gP1/RH4f4l/8jWn/wBe1/6VMKKKK9c/PAooooA8E/a7/wCZY/7e/wD2jXgle9/td/8AMsf9vf8A7RrwSvkcz/3qfy/JH9DcC/8AIhof9vf+lyCiiiuA+tCiiigD9B/2Qv8Ak3bwx/29/wDpXNXq9eUfshf8m7eGP+3v/wBK5q9XoAKKKKACiiigD8tf7X/6d/8Ax/8A+tR/a/8A07/+P/8A1qy6K/oH+1sX/P8Agv8AI/nf/W7OP+f3/ksf8jU/tf8A6d//AB//AOtR/a//AE7/APj/AP8AWrLoo/tbF/z/AIL/ACD/AFuzj/n9/wCSx/yNT+1/+nf/AMf/APrVXvr77TCI/K2YbOd2fX2qnRXNi8XWxlGVCs7xlo1ovy1KjxhnEXdVv/JY/wDyJ6D8BPhp/wALS8YXfh/+2v7I+z6e955/2Xz922SNNu3euP8AWZznt05r27/hjf8A6qL/AOUT/wC31yf7BH/JYNW/7AE3/pRb19t1+Q5/hKOExjp0VaNl3f5n69wfmOJzHLVXxMuaV2r2S29EkfKH/DG//VRf/KJ/9vo/4Y3/AOqi/wDlE/8At9fV9FeKfUHyh/wxv/1UX/yif/b663wZ+zV/wjuly2X/AAmf2rfMZd/9l7MZVRjHmn+7+tfQVFdOExlbB1Pa0XaXyf5nZgcfiMBV9th5cstr2T/O54x/won/AKmn/wAp/wD9sr58+L3iD/hAPiJqnhH7J/aX2Dyv9J8zyvM3wpJ9zDYxvx1PTNfdVfnx+15/ycR4o/7dP/SSGv0XgnMcTmePnRxUuaKg3ayWt4rol3Z9zw3xHmWNxUqdepdKLe0VrddkUP8AhaX/AFA//Jv/AOwo/wCFpf8AUD/8m/8A7CvN6K/UP7Ow38v4v/M+1+uVv5vyPSP+Fpf9QP8A8m//ALCuA1W6+3apd3vl+X9omeXZnO3cxOM9+tVqK4sbw7l2Oio16d0vOS/Jo87MMNSzGKjiVzJbdPysFFFFed/qRkf/AD4/8mn/APJHlf6t5Z/z7/GX+ZS+3/8ATL/x7/61H2//AKZf+Pf/AFqpUV/P5+VnWfD3xl/wifjCx8Qf2d9t+y+Z+58/y926Nk+9tOMbs9O1ezQftIebEH/4Q3Ge39p//aq+ba07H/j1T8f511UcZWoR5acrL5Hh5nw3lmaVVWxdPmkla95LS7fRruz6C/4aN/6k7/yp/wD2qj/ho3/qTv8Ayp//AGqvBKK1/tTFfzfgv8jzv9Rch/58f+TT/wDkj6Atv2h/Ocr/AMIhtwM/8hLP/tKrH/C/v+pT/wDKj/8Aa68A03/Xt/u/1FaFH9qYr+b8F/kH+ouQ/wDPj/yaf/yR2Pxe8cf8J/8A2X/xLP7N+wed/wAt/N3+Zs/2VxjZ79a4L7B/01/8d/8Ar1corkq1Z1ZOc3ds+iwGBoYChHD4ePLCN7K7e7u9Xd7s9Hi+CUY11NDu/FaW16Cxnkax/wBGiXzFSP8AfeYAzSfOUA4O0AkHdsr33wZMdnp93b+JVhhu7aG4ZtSsWtfKSQxndlWdSoSTfnIOI5cgbGx6VpgvD4k0tNSnt/M0yOQafc3Nu8wiSIzXBlS3iKsgVWgYKQrEIFVccjTW2lgj0ixuNas4Y7G9e9vfsgntzJAsgRZZEQ7lndZVQqAS4ccPtJTM6zxi2+FMJv5odS8QSaRbwmUST39iIdvlS7XyrS5A2bcE4BkdI+hLhIfhZY7bA3Pi6GD7dox1SJhZNKF2iTzY2CMWBRkTPyn5WYkKUKn2LR5bPVrG7u3spo7+3hs7Ow+zSyQn7dGFeO3Qup25IlXyyGdCJCT+9Vilp8twl1Lp/ilbiCa2ijne1js9lqY1mjW7zDJGsaBTuPGcjKlVQgA7n4NeKrPwN8LNF0GO3u9Utod628/kPBPI81xuQPCynZ80rKArOz+U5RXAbbtw/GHVJLeW8XwVM9nDEJXdJrjfIpRGHlhrYKSdz43MmBE5bYAceCWmqWn9myXejw2d9OggtbCW9sGuBAk0qYVkwY4RkTbSzytiRF3qwZm7DRfDljNqEkysdTis5YZQtq8ltE26cziSMsdseCC4Qt5TGQbCXJFAHd6n+0BbApL4f8J3uvWSXH2e5vILgRxLI2NgTeoLZJ2lmCKGwAW3KT0CfFDUk0ya+vfB1xZRspa1826Jz+6Z9s4EZaF9wjXbtckShgCFfb47qssNnpWrnWgk3iKynmeeaSdSiPJFLFH5QlUqgc7HTyxztcsUUBlNaWayvtG0uS6023huLdrK7lSeRltrtDHvd5GkTyyIrpUwSxCwou1gEWgD2K2+Kd5JYvdzeE7mBVdk8trgtLlSQWMSxmRUB2KSyg5kXAZSHONffHKS3ud0fhiCSwnVDY3J1UKbkylhCPL8sshcKcZ5O1yu5F3njY9TuprJF1jSYprO01bbaStIXu4n2Ilr+6j2LuLyQNkF38shX5AkOVoWmaXpWtut34pvdM1G6Z5UnvIfsS/vJInQxzEhLpV/fEIQ6kk7UwckA+TaKKK/cD+VAooooAKKKKAPoP8AYI/5LBq3/YAm/wDSi3r7br4k/YI/5LBq3/YAm/8ASi3r7br8y4p/5GD9Efu3h/8A8ieP+KQUUUV84fahRRRQAV+fH7Xn/JxHij/t0/8ASSGv0Hr8+P2vP+TiPFH/AG6f+kkNfoHht/yNKn/Xt/8ApUT6rhD/AH2f+F/mjyiiiiv2s/RgooooAKKKKAMWiiiv5UPw8K07H/j1T8f51mVp2P8Ax6p+P86AJ6KKKALOm/69v93+orQrP03/AF7f7v8AUVoUAFFFFAH0xb21svhy2065heS3lj8q+muHdLMQi4izhYyywupeTEO2ExNcBBgj52aQulXFnHd6bqYXTNJktpPNCSQSX7LutxNiKcsjDEcjSNF52JMAYAjaDT9b0/xBa/2kkFvqF9Z6Zd3RaDT4ZHMzusLyToFZCDtL/fyo3b90eQy3LW2l2ujaTYabLPDGLmGwS505nw6ymQOVEXnna7KzxeTt5fDEYyAWPDc9rcx3mmWBOrC01Nw8cUsaukSzKWht3JO5QRvzlt4mlVjE8uXr6c1vq8UtrYWr30t9ai6hvY3NvNbqBHIIzJvWIzx+eGa4jVnUhmkQ7nVdqCG9udC1S50/XNEudLtIxBa3FohiEckka27FZ44xF9pVWANwhIAY4TawRcyx8VaT/a19q8c19p7WxENvq8d1HtghKs6RTPLC8zfvVMZLKyAt5gGYlAAFi03WNWmtrqNtVj11bC41KK/tdS+y+aTbRtt2DaS7ERKVAVdqFFcpBtqx4gk0y50qe2gfT72LULqCGO5tTmTz7WFSkflsEWKVyIyymTOGCojPvKxeFZrS/iDQTi2vInk1TUrmBGISbzmjFwIVRlhkxIxDbMkBd+1YyGfY61NDDZxT2GdVSe0k1G4jtVe4JljdVkj8sM87MGlO9WWMOVUgKJA4A+21S5sdHW3vIbieOJZ2vdRaR2FvcLbytJsCK0gd953hoQqiMsY3walj8OaJFeztZtBqGnW1qsM9kkC75Y2iCrIrOqj9604crENoJVhJyqPk6HqbJrV3rOr2+pnT0WGNp9LvIJ5xmQlROw2STMVZywkwxEn3SwV6llhGm6QNAgjsrSS736bczbYg8iwTtIqG3W3kmLSJLjBU8opKsGAkAKWlSCPUdP1G/s/7J066mWwEo1qFhp0BtYYN6TyrvgZS4yiEPhRvHyxltyK4ju9RlNpqdtbro0tzZJayWkdrJJPJcAF0jVi2wOpOTsRAqDJImSsmPRru81PU/sup2mkWWoPFZvcw6nOYkRXaR1kOARchmZtnyjEnEXO+NZLqe08U2l5r1/P5pkaW+vkV1jV5oxFGWc4k2ebC0ke1QqIF2huwB8sUUUV+4H8qBRRRQAUUUUAfQf7BH/JYNW/7AE3/AKUW9fbdfEn7BH/JYNW/7AE3/pRb19t1+ZcU/wDIwfoj928P/wDkTx/xSCiiivnD7UKKKKACvz4/a8/5OI8Uf9un/pJDX6D1+fH7Xn/JxHij/t0/9JIa/QPDb/kaVP8Ar2//AEqJ9Vwh/vs/8L/NHlFFFFftZ+jBRRRQAUUUUAYtFFFfyofh4Vp2P/Hqn4/zrMrTsf8Aj1T8f50AT0UUUAWdN/17f7v9RWhWfpv+vb/d/qK0KACiiigD6PvLiH+ytL0+W3uNXs4ibu+bUbYymMSxPAIpVV44gzTFpQvmiRC7BtpVwbk9hY2ukTWEj2c2p6nY2Uuydg1tdSeYHEU8cW9maLby7BpCgkDSfOHrL1G+cale3zFI7eKCw/0GUslxsZGSO6QNDtjdDcq22FJAZTuPLL5mv4Tji1mHStL+wDTglgL630y0uPIjN8jO0EwKOpZRHtSVkVCJNoBL5VAClNdSalrllbXeoTalLNcwxq19abGhmUxEfZXkRUIdraQAyhHfyHQn70go3mn3viBtJk1a2vhZKgiWEyxPFg3nllnjtgsjqkJRgWCBiOCMbX0tX1XSfD95bXFvZzKunWyTabNcwI1jPJGd5e3ETw4cSSSO3yuChfbsU7m07CS9gsTdaqtxJpOrXq2EFtPrkSxTRtIImOJiyyxqVyjKqyghQHaNgVAOb+x67rOi6dbabeXU+iWazT2tvdWUk0lpbOJVjDhmEjKys8W+MuuUwoXYjPpapDDF4ov4rLTptRuNOk+1T6dA4imml8yJY2PkRbo5Y8lt0nmeYV3KXUBkTS9Li0/xTp95p8F1Hp1n5G4jTJoTJIZZJkgBmQvBCSr5bkbCgyOp0tC0zSLXU72bR4tcvb/zWuYLwQPcR3kLuRM8jRNGpWQSeYqRsEOYyxO5QACDQtS0e/bSdY1mC2it49RFvuYxi4trcyTyI/2nG9I4o1ClVA2kbMRFWJhXwjZaZ4Mm0qwkW5vYplsR9olbzsi4Z2GYkRgqOkrg4k5Vm6RyJVfxbc20Om3Wo6/pV7daothPbzLqV2YZby1BcI7eSGRvLzJ95zKu0ltxVHGpYWSrNb2iIszK5vJJxexJNZ2+5GEcxjYxiHyZPvyLgw7wEBkEdAENy97Gr6DFZafp+oXkS6bFZTOFthL+7VmEAmwXWNHhdiNpH2ZYyEZi9S1W01DwbNH4eNslvcxJBdxyzENZWssoOHeRok3NK08i5A+VwFVDIrVm6faCx825u57TxPbpd2ktpHNPceVAUEryfI0PmWmWAlZflUgsqlyjI/V3Wn3kbjUptRn/ALV0Vpkh0ryprvYzTDELeUFcoodeVh3NHLGSWVY9oB8cUUUV+4H8qBRRRQAUUUUAfQf7BH/JYNW/7AE3/pRb19t18SfsEf8AJYNW/wCwBN/6UW9fbdfmXFP/ACMH6I/dvD//AJE8f8Ugooor5w+1CiiigAr8+P2vP+TiPFH/AG6f+kkNfoPX58ftef8AJxHij/t0/wDSSGv0Dw2/5GlT/r2//Son1XCH++z/AML/ADR5RRRRX7WfowUUUUAFFFFAGLRRRX8qH4eFadj/AMeqfj/OsytOx/49U/H+dAE9FFFAFnTf9e3+7/UVoVn6b/r2/wB3+orQoAKKKKAPrO/tdAudXgNrYaNcRwmCFbiOxeWGORzJASzYkjMZMIhXeHCZj4XYwrD0pNIRdM1W31aX7bauH0wPOtzCpk3Z2QBSsaiZAQpljdVdMlWCx1FcteTeIdK0DU3t4b+9tZrM3Ane0vLtpJIwA0kDyRbmmgZldiEc5BQlmJl1HTbXSfDB02zv7rW47hbiVGFskuV8uOO28uRRFzmeJXwG3OxOPmKsAXzZadYT3ttbXtqlzYW8c1s1rbfZc26F08ySaKNX3oVkZiqhBKAJCu5UStZ6Te3WlTRTM+qWT2iNCdPaKNYhLbBYn2N5bBZnlc+c24bY4xIDg+Xn311qOl2w/tC6tb2W8tZoEaO5C3ey5LyfaWm8vZaxu0xbLnCLGCq/NkLcR6vpF/qejwX2p6l9tlnnnit7ApFLNKCY3l3KyyHKRoFWIRsblDlgcMAZgvLQaHLcXlpJZ3NrNvaSxhaQacILgobhlkRJdyhQhE/myES5Ux7WQ9Ff6fDfnTvD9551zqVza3OLBMCIiOIny2kSQJ96Nwh34ypiKLEuFzLx7bTJriS01AG98Oy3NtJfMIbQqSxSS4hijLBQGlQ5CZ2JEpKsEI1r7TtOtdItNOSDz7uNpLOeKxmt7gwGKzSHayv84by45VG5fvSksYC21ADP1zUdVTUItOkexuJ9Pu5FnlkmMT5cqGyS0UaxTnY0gRXMYm5KNIFD7S81E+FtJ1RNCktLaytZrrSDNsn+1yuq7WlBgAZggRvMjcuH3FmALOjtAmeE3V5FLrF/ImrRtphguRMJ3Ec0jAbF+Xlz5mcO4mVgQJCrWPDl1pNiH1KPUbmGz1Kf7c0VxfljOzT/ALtZWJcxZjOxWO0SiMhyS7RIAR6dpohvbCTT7yad4o5ZZpViuFTUZVgBLpkmRppGfYxjYq3lxfPuCRyUksNP8QJDHHbNKRcTQ2dkQkF+CtwhB3TMYo7gfOxCqN+2RnIkfaNkQyw3BttG1+KDTrGwL2w0PTFmjc7lV7ht291CmUcEMdyON37rIpXC6Xpd1YeJbmC28R6i92trcWkUf+jwSQRMkjSZjLKTErgRtydrnJCDYAf/2f/Y/+AAEEpGSUYAAQEAAAEAAQAA/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEFBQUHBgcOCAgOHhQRFB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e/8AAEQgA8AFAAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A+q6KKKACiiigAqhrn/Hov/XQfyNX6oa5/wAei/8AXQfyNfO8Wf8AImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf+QlH/wBcR/Nq6iuX8W/8hKP/AK4j+bV+l+Ev/JRR/wAEvyPz7xN/5EUv8UTHooor+pT+cAooooAK5y7/AOPub/ro38zXR1zl3/x9zf8AXRv5mvzDxP8A90of4n+R2YL4mRUUUV+NnohRRRQBQ8Q/8gaf/gP/AKEK5Cuv8Q/8gaf/AID/AOhCuQr+lPBv/kR1f+vsv/SIH9eeAH/JOV/+v0v/AEimFFFFfrB+4BRRRQBl69/yx/4F/SsutTXv+WP/AAL+lZdfzzx1/wAj6v8A9u/+kRPWw38JBRRRXyRuFFFFAHH+Iv8AkMz/APAf/QRWfWh4i/5DM/8AwH/0EVn1/aXCv/IjwX/Xqn/6Qj+SeJP+Rxi/+vk//SmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/49F/66D+Rq/VDXP+PRf+ug/ka+d4s/5E2I/wAJrQ/iIxqKKK/m49gKKKKACuX8W/8AISj/AOuI/m1dRXL+Lf8AkJR/9cR/Nq/S/CX/AJKKP+CX5H594m/8iKX+KJj0UUV/Up/OAUUUUAFc5d/8fc3/AF0b+Zro65y7/wCPub/ro38zX5h4n/7pQ/xP8jswXxMiooor8bPRCiiigCh4h/5A0/8AwH/0IVyFdf4h/wCQNP8A8B/9CFchX9KeDf8AyI6v/X2X/pED+vPAD/knK/8A1+l/6RTCiiiv1g/cAooooAy9e/5Y/wDAv6Vl1qa9/wAsf+Bf0rLr+eeOv+R9X/7d/wDSInrYb+Egooor5I3CiiigDj/EX/IZn/4D/wCgis+tDxF/yGZ/+A/+gis+v7S4V/5EeC/69U//AEhH8k8Sf8jjF/8AXyf/AKUwooor3jxQooooA/Taiiiv5MPdCiiigAqhrn/Hov8A10H8jV+qGuf8ei/9dB/I187xZ/yJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/kJR/9cR/Nq6iuX8W/8hKP/riP5tX6X4S/8lFH/BL8j8+8Tf8AkRS/xRMeiiiv6lP5wCiiigArnLv/AI+5v+ujfzNdHXOXf/H3N/10b+Zr8w8T/wDdKH+J/kdmC+JkVFFFfjZ6IUUUUAUPEP8AyBp/+A/+hCuQrr/EP/IGn/4D/wChCuQr+lPBv/kR1f8Ar7L/ANIgf154Af8AJOV/+v0v/SKYUUUV+sH7gFFFFAGXr3/LH/gX9Ky61Ne/5Y/8C/pWXX888df8j6v/ANu/+kRPWw38JBRRRXyRuFFFFAHH+Iv+QzP/AMB/9BFZ9aHiL/kMz/8AAf8A0EVn1/aXCv8AyI8F/wBeqf8A6Qj+SeJP+Rxi/wDr5P8A9KYUUUV7x4oUUUUAfptRRRX8mHuhRRRQAVQ1z/j0X/roP5Gr9UNc/wCPRf8AroP5GvneLP8AkTYj/Ca0P4iMaiiiv5uPYCiiigArl/Fv/ISj/wCuI/m1dRXL+Lf+QlH/ANcR/Nq/S/CX/koo/wCCX5H594m/8iKX+KJj0UUV/Up/OAUUUUAFc5d/8fc3/XRv5mujrnLv/j7m/wCujfzNfmHif/ulD/E/yOzBfEyKiiivxs9EKKKKAKHiH/kDT/8AAf8A0IVyFdf4h/5A0/8AwH/0IVyFf0p4N/8AIjq/9fZf+kQP688AP+Scr/8AX6X/AKRTCiiiv1g/cAooooAy9e/5Y/8AAv6Vl1qa9/yx/wCBf0rLr+eeOv8AkfV/+3f/AEiJ62G/hIKKKK+SNwooooA4/wARf8hmf/gP/oIrPrQ8Rf8AIZn/AOA/+gis+v7S4V/5EeC/69U//SEfyTxJ/wAjjF/9fJ/+lMKKKK948UKKKKAP02ooor+TD3QooooAKoa5/wAei/8AXQfyNX6oa5/x6L/10H8jXzvFn/ImxH+E1ofxEY1FFFfzcewFFFFABXL+Lf8AkJR/9cR/Nq6iuX8W/wDISj/64j+bV+l+Ev8AyUUf8EvyPz7xN/5EUv8AFEx6KKK/qU/nAKKKKACucu/+Pub/AK6N/M10dc5d/wDH3N/10b+Zr8w8T/8AdKH+J/kdmC+JkVFFFfjZ6IUUUUAUPEP/ACBp/wDgP/oQrkK6/wAQ/wDIGn/4D/6EK5Cv6U8G/wDkR1f+vsv/AEiB/XngB/yTlf8A6/S/9IphRRRX6wfuAUUUUAZevf8ALH/gX9Ky61Ne/wCWP/Av6Vl1/PPHX/I+r/8Abv8A6RE9bDfwkFFFFfJG4UUUUAcf4i/5DM//AAH/ANBFZ9aHiL/kMz/8B/8AQRWfX9pcK/8AIjwX/Xqn/wCkI/kniT/kcYv/AK+T/wDSmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/49F/66D+Rq/VDXP+PRf+ug/ka+d4s/5E2I/wmtD+IjGooor+bj2AooooAK5fxb/yEo/+uI/m1dRXL+Lf+QlH/wBcR/Nq/S/CX/koo/4Jfkfn3ib/AMiKX+KJj0UUV/Up/OAUUUUAFc5d/wDH3N/10b+Zro65y7/4+5v+ujfzNfmHif8A7pQ/xP8AI7MF8TIqKKK/Gz0QooooAoeIf+QNP/wH/wBCFchXX+If+QNP/wAB/wDQhXIV/Sng3/yI6v8A19l/6RA/rzwA/wCScr/9fpf+kUwooor9YP3AKKKKAMvXv+WP/Av6Vl1qa9/yx/4F/Ssuv5546/5H1f8A7d/9Iiethv4SCiiivkjcKKKKAOP8Rf8AIZn/AOA/+gis+tDxF/yGZ/8AgP8A6CKz6/tLhX/kR4L/AK9U/wD0hH8k8Sf8jjF/9fJ/+lMKKKK948UKKKKAP02ooor+TD3QooooAKoa5/x6L/10H8jV+qGuf8ei/wDXQfyNfO8Wf8ibEf4TWh/ERjUUUV/Nx7AUUUUAFcv4t/5CUf8A1xH82rqK5fxb/wAhKP8A64j+bV+l+Ev/ACUUf8EvyPz7xN/5EUv8UTHooor+pT+cAooooAK5y7/4+5v+ujfzNdHXOXf/AB9zf9dG/ma/MPE//dKH+J/kdmC+JkVFFFfjZ6IUUUUAUPEP/IGn/wCA/wDoQrkK6/xD/wAgaf8A4D/6EK5Cv6U8G/8AkR1f+vsv/SIH9eeAH/JOV/8Ar9L/ANIphRRRX6wfuAUUUUAZevf8sf8AgX9Ky61Ne/5Y/wDAv6Vl1/PPHX/I+r/9u/8ApET1sN/CQUUUV8kbhRRRQBx/iL/kMz/8B/8AQRWfWh4i/wCQzP8A8B/9BFZ9f2lwr/yI8F/16p/+kI/kniT/AJHGL/6+T/8ASmFFFFe8eKFFFFAH6bUUUV/Jh7oUUUUAFUNc/wCPRf8AroP5Gr9UNc/49F/66D+Rr53iz/kTYj/Ca0P4iMaiiiv5uPYCiiigArl/Fv8AyEo/+uI/m1dRXL+Lf+QlH/1xH82r9L8Jf+Sij/gl+R+feJv/ACIpf4omPRRRX9Sn84BRRRQAVzl3/wAfc3/XRv5mujrnLv8A4+5v+ujfzNfmHif/ALpQ/wAT/I7MF8TIqKKK/Gz0QooooAoeIf8AkDT/APAf/QhXIV1/iH/kDT/8B/8AQhXIV/Sng3/yI6v/AF9l/wCkQP688AP+Scr/APX6X/pFMKKKK/WD9wCiiigDL17/AJY/8C/pWXWpr3/LH/gX9Ky6/nnjr/kfV/8At3/0iJ62G/hIKKKK+SNwooooA4/xF/yGZ/8AgP8A6CKz60PEX/IZn/4D/wCgis+v7S4V/wCRHgv+vVP/ANIR/JPEn/I4xf8A18n/AOlMKKKK948UKKKKAP02ooor+TD3QooooAKoa5/x6L/10H8jV+qGuf8AHov/AF0H8jXzvFn/ACJsR/hNaH8RGNRRRX83HsBRRRQAVy/i3/kJR/8AXEfzauorl/Fv/ISj/wCuI/m1fpfhL/yUUf8ABL8j8+8Tf+RFL/FEx6KKK/qU/nAKKKKACucu/wDj7m/66N/M10dc5d/8fc3/AF0b+Zr8w8T/APdKH+J/kdmC+JkVFFFfjZ6IUUUUAUPEP/IGn/4D/wChCuQrr/EP/IGn/wCA/wDoQrkK/pTwb/5EdX/r7L/0iB/XngB/yTlf/r9L/wBIphRRRX6wfuAUUUUAZevf8sf+Bf0rLrU17/lj/wAC/pWXX888df8AI+r/APbv/pET1sN/CQUUUV8kbhRRRQBx/iL/AJDM/wDwH/0EVn1oeIv+QzP/AMB/9BFZ9f2lwr/yI8F/16p/+kI/kniT/kcYv/r5P/0phRRRXvHihRRRQB+m1FFFfyYe6FFFFABVDXP+PRf+ug/kav1Q1z/j0X/roP5GvneLP+RNiP8ACa0P4iMaiiiv5uPYCiiigArl/Fv/ACEo/wDriP5tXUVy/i3/AJCUf/XEfzav0vwl/wCSij/gl+R+feJv/Iil/iiY9FFFf1KfzgFFFFABXOXf/H3N/wBdG/ma6Oucu/8Aj7m/66N/M1+YeJ/+6UP8T/I7MF8TIqKKK/Gz0QooooAoeIf+QNP/AMB/9CFchXX+If8AkDT/APAf/QhXIV/Sng3/AMiOr/19l/6RA/rzwA/5Jyv/ANfpf+kUwooor9YP3AKKKKAMvXv+WP8AwL+lZdamvf8ALH/gX9Ky6/nnjr/kfV/+3f8A0iJ62G/hIKKKK+SNwooooA4/xF/yGZ/+A/8AoIrPrQ8Rf8hmf/gP/oIrPr+0uFf+RHgv+vVP/wBIR/JPEn/I4xf/AF8n/wClMKKKK948UKKKKACiiigAooooAKoa5/x6L/10H8jV+qGuf8ei/wDXQfyNfPcWf8ibEf4Tah/ERjUUUV/Np64UUUUAFetfBn/kV7n/AK/W/wDQEryWvWvgz/yK9z/1+t/6AlfS8J/8jFejPr+B/wDkar/CztqKKK/UT9nCiiigArwHxV/yM+q/9fs3/obV79XgPir/AJGfVf8Ar9m/9DavjONP4FL1f5H594hf7tR/xP8AIzaKKK/PD8qCiiigDvf2ev8AksGh/wDbx/6TyV9c18jfs9f8lg0P/t4/9J5K+ua+myX+A/X9Efh/iX/yNaf/AF7X/pUwooor1z88CiiigDwT9rv/AJlj/t7/APaNeCV73+13/wAyx/29/wDtGvBK+RzP/ep/L8kf0NwL/wAiGh/29/6XIKKKK4D60KKKKAP0H/ZC/wCTdvDH/b3/AOlc1er15R+yF/ybt4Y/7e//AErmr1egAooooAKKKKAPy1/tf/p3/wDH/wD61H9r/wDTv/4//wDWrLor+gf7Wxf8/wCC/wAj+d/9bs4/5/f+Sx/yNT+1/wDp3/8AH/8A61H9r/8ATv8A+P8A/wBasuij+1sX/P8Agv8AIP8AW7OP+f3/AJLH/I1P7X/6d/8Ax/8A+tVe+vvtMIj8rZhs53Z9faqdFc2LxdbGUZUKzvGWjWi/LUqPGGcRd1W/8lj/APInoPwE+Gn/AAtLxhd+H/7a/sj7Pp73nn/ZfP3bZI027d64/wBZnOe3Tmvbv+GN/wDqov8A5RP/ALfXJ/sEf8lg1b/sATf+lFvX23X5Dn+Eo4TGOnRVo2Xd/mfr3B+Y4nMctVfEy5pXavZLb0SR8of8Mb/9VF/8on/2+j/hjf8A6qL/AOUT/wC319X0V4p9QfKH/DG//VRf/KJ/9vrrfBn7NX/CO6XLZf8ACZ/at8xl3/2XsxlVGMeaf7v619BUV04TGVsHU9rRdpfJ/mdmBx+IwFX22Hlyy2vZP87njH/Cif8Aqaf/ACn/AP2yvnz4veIP+EA+ImqeEfsn9pfYPK/0nzPK8zfCkn3MNjG/HU9M191V+fH7Xn/JxHij/t0/9JIa/ReCcxxOZ4+dHFS5oqDdrJa3iuiXdn3PDfEeZY3FSp16l0ot7RWt12RQ/wCFpf8AUD/8m/8A7Cj/AIWl/wBQP/yb/wDsK83or9Q/s7Dfy/i/8z7X65W/m/I9I/4Wl/1A/wDyb/8AsK4DVbr7dql3e+X5f2iZ5dmc7dzE4z361WorixvDuXY6KjXp3S85L8mjzsww1LMYqOJXMlt0/KwUUUV53+pGR/8APj/yaf8A8keV/q3ln/Pv8Zf5lL7f/wBMv/Hv/rUfb/8Apl/49/8AWqlRX8/n5WdZ8PfGX/CJ+MLHxB/Z3237L5n7nz/L3bo2T7204xuz07V7NB+0h5sQf/hDcZ7f2n/9qr5trTsf+PVPx/nXVRxlahHlpysvkeHmfDeWZpVVbF0+aSVr3ktLt9Gu7PoL/ho3/qTv/Kn/APaqP+Gjf+pO/wDKn/8Aaq8EorX+1MV/N+C/yPO/1FyH/nx/5NP/AOSPoC2/aH85yv8AwiG3Az/yEs/+0qsf8L+/6lP/AMqP/wBrrwDTf9e3+7/UVoUf2piv5vwX+Qf6i5D/AM+P/Jp//JHY/F7xx/wn/wDZf/Es/s37B53/AC383f5mz/ZXGNnv1rgvsH/TX/x3/wCvVyiuSrVnVk5zd2z6LAYGhgKEcPh48sI3srt7u71d3uzuIPhGstq1xHr81wiaoLBjZ6XJccNLsSTCMWUFQXwyqSCm3fvBGppXwKN3rq6TN4qjjkNs0jNBY/aNsyq7NAdkhG/93IQM5YIxAJVlHo+o6zezaPa2d7pMQuNPijeS31CcbGQ2+24lSK4mZWWIwIVKkBvOJ4Vm8xus3d7bXv8AYVhoEevR6gRMj+Rb3JFxEP35kDGRTIz712BjgSfJjhpMzrPJD8G9XkTTGsp7i7S+laMTLarHECrlCis8ikybkkXDBV3BAGO/Iv658EZrL7RFp/iJdWu7YSCWC2sjhZEODGZC/l7xui3KGLAs20MFyfS9dm1e71caXcWsli1oJdONilwsZfTnlgEZR49oCuzPCoKMpTaoUkSPT9Rs72B5rSTSpZNXZ2bUHs7OR7l5S+BcW8KSriSNxJtduzwjaY/3igHd/CXxHL8PvA1j4Pj0uTWLXTIJ2F+sywPPNIJLpIFt2/eeYytgJgscq20A8bqfGdbi3hSz8Pbr14BK8M940ahvlyiHyi0zKreYwjViqckBsIfDdMuBYavfXcqRwwraR26217aBFsowkhkiDzMVAWZdoLP5YdjmMsAE6DT7TytVW202+vrbTrY74Zo9HUQxSsghBEaRktPhZUcsqOrCY7V2nAB6jcfFrXoA9y/g7T20+3RXvrmPXC5tFKli0kQg8xFCgnLqucYGWKg2x8WZ4r9NPufC5luntxdBbHU4p08rZuJ3tsXKkMDztAGd3IFeQ6Ppmn6oNCnsp5bzz9OjfULgWpt7hYJVLbl+TZ5gljdo0VXlkKM/m4ALQ2Wu2mq64k4s7DyJ5TY3ENzqysrNLOVwimQvA0sCuqlHYEjIQIxZgD1rTfjRHd/b3Gh2zxWEqxXBt9TEjRMV3HflFUAYIJDEE/d3AMVsWfxanlsbq7m8OLstZRFL5N3IygmOR9wd4UjaMbFG9WI5YjOE8zw/w5fPqTix07W0vHjjGrTXcgYSOiRwHdcyQb87FZldOQ5Uk7WIkro/Ec0TaxYyalqVnpUkV5Paw3c8m8zwShI/PlGY1CsICrJtyA/UhZSoB8gUUUV+4H8qBRRRQAUUUUAfQf7BH/JYNW/7AE3/AKUW9fbdfEn7BH/JYNW/7AE3/pRb19t1+ZcU/wDIwfoj928P/wDkTx/xSCiiivnD7UKKKKACvz4/a8/5OI8Uf9un/pJDX6D1+fH7Xn/JxHij/t0/9JIa/QPDb/kaVP8Ar2//AEqJ9Vwh/vs/8L/NHlFFFFftZ+jBRRRQAUUUUAYtFFFfyofh4Vp2P/Hqn4/zrMrTsf8Aj1T8f50AT0UUUAWdN/17f7v9RWhWfpv+vb/d/qK0KACiiigD6Uurg+FdHuD4WS0fRC9vcLO8v+m3MMgllR43Drn5xc4SYMV8uNijbmKv8X6Ob+K21iaxsP7av5IfKhuIgjPB/qGckSj5GVGkP7p1jWVfuguwzru3uLnQ7/QZdEmiiSMNbrcpFbos4iRmMQcJO7lYUdxGMLvwIiFVjpm8W4s7xb6DUtOGogP9ognZrdRseNoxvQGIiNpbcMke4bYQvmu7K4Bam1HWdPgupk0uTS7c26wx20ySeZaXIVIpZLZZJniULJ5RRmAJMq4JJcNWhGqWMOo6NHd6Sl7pM6QXZvW37LeRVga4ERZQS+ISkewM25NrMHdS6KLRNH8PXM0lzrTaddwXT/6LDJBGLeVkmxI5dkSKTiFWiTYWErGTnclXXrSLStCWGS4l05rV5pr24sYGuGnj84usdvPLE7LIHPyMGyjK8mCrLKAC7ea5rOqeJbyYs11c2oSSBDbRyXKxRmdpjHBtCRsNwjHmKd8nzEH5Ajf+EVX+3c29otnMtjG1xcpFNJGbjy2jaOdGfYZ/36FN7rndksUASXK0SfTbjRriy1HS9Supyyix0+K8R5Zrhp5RHH5a4KQJHJCMKFVdxKqjNk6l3F4esWiivpH1WFIY3tbe3lmhe3EiWywywLIPMjnZA4GZNxMAbBYuAAUNQurPR7qe31pobuHU4be3jstUmEgtWB/e3Th2BaJrqEiUSFSQEYuWG2OzqunSxTLo82q6lrF158011PZSwtAZ7m2cCZEOwoWN1I4ZpMkQs6x7MFK+qXMCaVLpmoIIL+5sWvYJ7K4aZ72JVnQSQhIj5aklUj3noyA42ulX7/QL+4TVLW90+8htETUACZjZwSxhLhkWH96VCoV+ZGYEiaYguobIBe1m7tn8Tam9vDpmny+IbdpC07O1xaodsZl8k7ZA8cIkLESKFLOE37HrG8NyXn9hw3Hh+8Gn2m9Ga1mv43W2RXMAjZ2d1fzyqIjFVTaTwF2ml122+yaW+peILXWdThvbjyJZS0mNvkojRCRkeTcJ4VTIXbgqRtZauWdyNI0CK2029g0DUI5vt9sJ2WCOMskkamNWikdd4VflbHyMfOG7c8wB8j0UUV+4H8qBRRRQAUUUUAfQf7BH/JYNW/7AE3/pRb19t18SfsEf8lg1b/sATf8ApRb19t1+ZcU/8jB+iP3bw/8A+RPH/FIKKKK+cPtQooooAK/Pj9rz/k4jxR/26f8ApJDX6D1+fH7Xn/JxHij/ALdP/SSGv0Dw2/5GlT/r2/8A0qJ9Vwh/vs/8L/NHlFFFFftZ+jBRRRQAUUUUAYtFFFfyofh4Vp2P/Hqn4/zrMrTsf+PVPx/nQBPRRRQBZ03/AF7f7v8AUVoVn6b/AK9v93+orQoAKKKKAPprXoNR1LxVcwRatqLF7i0hllmljtp9R2NIJoo34kw6RglYwnzIAEkOXpyRy6TaWt3aWrXGlssUclgsyW91ayKytHZqqsnnzrI0aq2wkq7HLLNtNfUr/Wk8Q3upvp+n2X2aR4IytunmzCLPnyKJVjL3JhKjzNoLIpQBRlytz4d1O/js7XXNNvYobe5mj/s++lM/lF5VjV4JlkiWL94rlUaVt+flDABiATu7alb6kt9PJfafcWVzpts9pcLqQiVmSR7iXBjaQHytxkBJ3LhhGy4rEu57ezuJry3ihljudKkGkw2ttKVhaDbcF5be425hcmSbJLDMbkBt5Vpnvs21psluZ9TitzY2N5ZrPIFt5IYxyhzuBVndQ7p81sCwh/eqNbQSI73TzrF1pNtqM19Ndssd19kW1WVi7PPAXLz8orYVflKIPNURZABX0nWllj1DR7m1ntdRk2NcQi6gN7eyMZVWO4CIsMKtLd5CsjMPLYOGaWFW09NvY9O17UvE8fhJ5NKYHyILBylvHcAxFm+zkgyojSHJRd4dZHKAsQnPeHbSXUUvv+Eo0qwgZbbzbgvC8F95iSHDNcFkuCPPyN7CUKLdQ4JzIbvia5YeGZtT8VWWj6NfancW9zAbKCS4adt3zNEpdAGKSBkZdzBXnXPmAhACx/Zut+FtO05nnuppZ0RlsI9cNpBaOV2p9oEhLFlSFnDR4wY5FCrt3HBkh0PVpb17iz1KfXhDJHBb3pZy7yGV0BVGwCsaTM4diu4OV2FgBr+Ep9PtNEu7xJNOS01C8tJ4ZYLc2iy2vmzPPEI1dJFlRfPAALNLHIqYZTuFGxsbrSZrC4h1C1upkuPssyz2amWC3UrJ5KK5KySRneXYbGWVgNxlcqwBoapevaeK/Dl5qFs8erG5js1iuZmiZyVg37AzL5O93mEjRgKc7WDOxDVdPeC83eFrPUYYfDcMrWTTWMlwY3SBpbuWSKNS4MipEFUqfMfIkfO9QluF2TUZprWxt9ZhtLmZJ2tII7w/vkVfs/l7y6iY/aSpYHmZv3TM+RoePtd02yvvEGkWenC6k/s+5SSVbs3MayeTbeeuI2MgkHlKA0igp5TSEsHYqAfH1FFFfuB/KgUUUUAFFFFAH0H+wR/yWDVv+wBN/wClFvX23XxJ+wR/yWDVv+wBN/6UW9fbdfmXFP8AyMH6I/dvD/8A5E8f8Ugooor5w+1CiiigAr8+P2vP+TiPFH/bp/6SQ1+g9fnx+15/ycR4o/7dP/SSGv0Dw2/5GlT/AK9v/wBKifVcIf77P/C/zR5RRRRX7WfowUUUUAFFFFAGLRRRX8qH4eFadj/x6p+P86zK07H/AI9U/H+dAE9FFFAFnTf9e3+7/UVoVn6b/r2/3f6itCgAooooA+iv7SvNG1SOx0+2m1JXKx6ZqscUF4LaJppFlQbVLs0piuUVPN6ZAIU7V0dQGmPpTW7Xsdy1iJoReRJLLG0Qt5JGefYFDyndgSuVEyPMcbXKl1tY3sEIi13RdPil07TJWstKu5hJLE8kqvJKkYljHlLmWNQrn5JIVJOJCItP+1Sa1B4jFrHcx6nFEZ7FdM+0zE+XNC0DRyB3CiRgskpAdlaY7l8xUAA66S5sNWc2Njf3FpJaL9naKOF22S3f2hdoli+QB2diyCSLm33M6kES+JtMsbbXNKGraLqC654gi3ahYXN4UtI4iEBtxJE6oGHlhgxYtvVSV5QLT8LfZ7TxBZzWNpc3trcxXCSWd6tvGrSkIZGf94qyR+QQeI1UxxAhCxEgzoBYX2hza/PokKQ+Ub3LTxwxWVxMixL5aFmeGMB5GTapcmOKQNgosYBJbrZTWjDxFpttayTXMUMupTWhjjaJUEix7FAMgWdH3j5ZCyorAjeIp7vUtX0PV9F/tDULnTY7OUXgguIpLiWCBmcxyiVyQ5WHdEvyZ3K+5V3Oxs3Njpuo2lvLEZ9RvU0topHBSe6uWihNvOIwspMoYMVKwvsO04BaMFo4pP7d0S60jTtbvpJI1FtLZywL5t6HYB4j5Thoyjbnw4VnaQLIZB87gEFhbz674y07SvtVnHf2zvZTRBJ2iit3jwIWtnijnIMUxUTGRuImJZUbjd1W9h0LQr291LRixLRQ20Glq1wsUEQQJ5YAwuyGU4bzQQSCN0cmKlu9I1hJNav5NaugLmdLW7fY6izztMUyKXaZXLNblISw2Btu4OuIuan/ALY1TQxZ6tZT31nfXFqtusyNZw3DTAlp1VGkB/evuYuuNrFUMZ2KACY2tpeRJrZhsb3TpZbZpLrVdgd4YYYVWOFvLbLPI6wtKqkEWwO5sEiXU9P0PVfDljp+oSadcXsll9mN7czRJcWTLI8gt4pJc7ZBJvB3bQsYO0lgzPBLpXia9lmS/wBNt4bzT7rykkuLDeVhdEbbFvk2ySINn+j8goCoZ1fbSWk+iwatd69LDrd1rd5qMVtpw1GDLQRXDsCGtzJtkyZDNs6Fnj+VQ2QAf//Z\n", 188 | "text/plain": [ 189 | "" 190 | ] 191 | }, 192 | "execution_count": 13, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | } 196 | ], 197 | "source": [ 198 | "from IPython.display import Video, Image\n", 199 | "Image(\"videotestsrc-frame.jpg\")" 200 | ] 201 | } 202 | ], 203 | "metadata": { 204 | "kernelspec": { 205 | "display_name": "Python 3", 206 | "language": "python", 207 | "name": "python3" 208 | }, 209 | "language_info": { 210 | "codemirror_mode": { 211 | "name": "ipython", 212 | "version": 3 213 | }, 214 | "file_extension": ".py", 215 | "mimetype": "text/x-python", 216 | "name": "python", 217 | "nbconvert_exporter": "python", 218 | "pygments_lexer": "ipython3", 219 | "version": "3.6.9" 220 | } 221 | }, 222 | "nbformat": 4, 223 | "nbformat_minor": 5 224 | } 225 | -------------------------------------------------------------------------------- /archive/.ipynb_checkpoints/02-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 3, 6 | "id": "5367f1e9-1543-45d4-849f-a6aad602f596", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "typefindfunctions: application/x-id3v2: mp3, mp2, mp1, mpga, ogg, flac, tta\n", 14 | "typefindfunctions: application/x-id3v1: mp3, mp2, mp1, mpga, ogg, flac, tta\n", 15 | "typefindfunctions: application/x-apetag: mp3, ape, mpc, wv\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "!gst-inspect-1.0 | grep mp3 | head -3" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "id": "c5bde50c-edda-4a30-a815-9740af438137", 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "WARNING: erroneous pipeline: no element \"xvimagesink\"\n" 34 | ] 35 | } 36 | ], 37 | "source": [ 38 | "!gst-launch-1.0 v4l2src ! xvimagesink" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 1, 44 | "id": "16159f6f-7112-4ee3-af40-1d12b623ab36", 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "01.ipynb 03.ipynb README.md \u001b[0m\u001b[01;34mtest1\u001b[0m/ untitled1.py\n", 52 | "02.ipynb 04.ipynb \u001b[01;32mdocker_run.sh\u001b[0m* untitled.py videotestsrc-frame.jpg\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "ls" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "id": "7b7f1121-7597-471a-9060-6ef80e7fb2fa", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "!cd test1" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 2, 73 | "id": "4147bca5-fec0-49ee-85c1-4639c56f5903", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "# Set some path locations for readability\n", 78 | "PYTHON_APPS = '/opt/nvidia/deepstream/deepstream/sources/deepstream_python_apps/apps'\n", 79 | "STREAMS = '/opt/nvidia/deepstream/deepstream/samples/streams'" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "id": "ca0c3e1b-f955-48bd-845a-b1046d1c564a", 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "sample_1080p_h264.mp4 sample_720p.mp4\t sample_qHD.mp4\t yoga.jpg\n", 93 | "sample_1080p_h265.mp4 sample_cam6.mp4\t sample_ride_bike.mov yoga.mp4\n", 94 | "sample_720p.h264 sample_industrial.jpg sample_run.mov\n", 95 | "sample_720p.jpg sample_push.mov\t sample_walk.mov\n", 96 | "sample_720p.mjpeg sample_qHD.h264\t sonyc_mixed_audio.wav\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "# List the sample video streams available\n", 102 | "!ls $STREAMS" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 4, 108 | "id": "1c6eece3-f8ca-4d0f-8841-4e7e414ef948", 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "# update model path by ../../" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 5, 118 | "id": "2e76eccc-c70a-42f7-b7f0-b5fd959e0bc9", 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "Creating Pipeline \n", 126 | " \n", 127 | "Creating Source \n", 128 | " \n", 129 | "Creating H264Parser \n", 130 | "\n", 131 | "Creating Decoder \n", 132 | "\n", 133 | "Creating EGLSink \n", 134 | "\n", 135 | "Playing file /opt/nvidia/deepstream/deepstream/samples/streams/sample_720p.h264 \n", 136 | "Adding elements to Pipeline \n", 137 | "\n", 138 | "Linking elements in the Pipeline \n", 139 | "\n", 140 | "Starting pipeline \n", 141 | "\n", 142 | "\n", 143 | "Using winsys: x11 \n", 144 | "Opening in BLOCKING MODE \n", 145 | "0:00:01.721230893 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[33;01mWARN \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:635:gst_nvinfer_logger:\u001b[00m NvDsInferContext[UID 1]: Warning from NvDsInferContextImpl::initialize() [UID = 1]: Warning, OpenCV has been deprecated. Using NMS for clustering instead of cv::groupRectangles with topK = 20 and NMS Threshold = 0.5\n", 146 | "ERROR: Deserialize engine failed because file path: /opt/nvidia/deepstream/deepstream-6.0/sources/deepstream_python_apps/my_apps/edge-computing/video_ai_app/test1/../../../../../../samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine open error\n", 147 | "0:00:06.192745886 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[33;01mWARN \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:635:gst_nvinfer_logger:\u001b[00m NvDsInferContext[UID 1]: Warning from NvDsInferContextImpl::deserializeEngineAndBackend() [UID = 1]: deserialize engine from file :/opt/nvidia/deepstream/deepstream-6.0/sources/deepstream_python_apps/my_apps/edge-computing/video_ai_app/test1/../../../../../../samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine failed\n", 148 | "0:00:06.193949024 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[33;01mWARN \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:635:gst_nvinfer_logger:\u001b[00m NvDsInferContext[UID 1]: Warning from NvDsInferContextImpl::generateBackendContext() [UID = 1]: deserialize backend context from engine from file :/opt/nvidia/deepstream/deepstream-6.0/sources/deepstream_python_apps/my_apps/edge-computing/video_ai_app/test1/../../../../../../samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine failed, try rebuild\n", 149 | "0:00:06.194001837 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[36mINFO \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:638:gst_nvinfer_logger:\u001b[00m NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::buildModel() [UID = 1]: Trying to create engine from model files\n", 150 | "WARNING: INT8 not supported by platform. Trying FP16 mode.\n", 151 | "0:02:58.109615825 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[36mINFO \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:638:gst_nvinfer_logger:\u001b[00m NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::buildModel() [UID = 1]: serialize cuda engine to file: /opt/nvidia/deepstream/deepstream-6.0/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_fp16.engine successfully\n", 152 | "INFO: [Implicit Engine Info]: layers num: 3\n", 153 | "0 INPUT kFLOAT input_1 3x368x640 \n", 154 | "1 OUTPUT kFLOAT conv2d_bbox 16x23x40 \n", 155 | "2 OUTPUT kFLOAT conv2d_cov/Sigmoid 4x23x40 \n", 156 | "\n", 157 | "0:02:58.915700387 \u001b[332m 463\u001b[00m 0x267ab30 \u001b[36mINFO \u001b[00m \u001b[00m nvinfer gstnvinfer_impl.cpp:313:notifyLoadModelStatus:\u001b[00m [UID 1]: Load new model:dstest1_pgie_config.txt sucessfully\n", 158 | "NvMMLiteOpen : Block : BlockType = 261 \n", 159 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 160 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 161 | "Frame Number=0 Number of Objects=9 Vehicle_count=6 Person_count=3\n", 162 | "0:03:00.873124491 \u001b[332m 463\u001b[00m 0x2212a80 \u001b[33;01mWARN \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:2288:gst_nvinfer_output_loop:\u001b[00m error: Internal data stream error.\n", 163 | "0:03:00.873179804 \u001b[332m 463\u001b[00m 0x2212a80 \u001b[33;01mWARN \u001b[00m \u001b[00m nvinfer gstnvinfer.cpp:2288:gst_nvinfer_output_loop:\u001b[00m error: streaming stopped, reason error (-5)\n", 164 | "Frame Number=1 Number of Objects=10 Vehicle_count=7 Person_count=3\n", 165 | "Error: gst-stream-error-quark: Internal data stream error. (1): /dvs/git/dirty/git-master_linux/deepstream/sdk/src/gst-plugins/gst-nvinfer/gstnvinfer.cpp(2288): gst_nvinfer_output_loop (): /GstPipeline:pipeline0/GstNvInfer:primary-inference:\n", 166 | "streaming stopped, reason error (-5)\n", 167 | "Frame Number=2 Number of Objects=10 Vehicle_count=7 Person_count=3\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "!cd test1 \\\n", 173 | " && python3 deepstream_test_1.py $STREAMS/sample_720p.h264" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "id": "02816bb7-f00b-4db7-a2ad-9f421c47e014", 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "# /dli/task/deepstream/sources/deepstream_python_apps/apps/deepstream-test1 -reference " 184 | ] 185 | } 186 | ], 187 | "metadata": { 188 | "kernelspec": { 189 | "display_name": "Python 3", 190 | "language": "python", 191 | "name": "python3" 192 | }, 193 | "language_info": { 194 | "codemirror_mode": { 195 | "name": "ipython", 196 | "version": 3 197 | }, 198 | "file_extension": ".py", 199 | "mimetype": "text/x-python", 200 | "name": "python", 201 | "nbconvert_exporter": "python", 202 | "pygments_lexer": "ipython3", 203 | "version": "3.6.9" 204 | } 205 | }, 206 | "nbformat": 4, 207 | "nbformat_minor": 5 208 | } 209 | -------------------------------------------------------------------------------- /archive/.ipynb_checkpoints/03-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "7eb36929-30b8-4ee2-ae83-26de93edcbc0", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n", 14 | "Opening in BLOCKING MODE \n", 15 | "NvMMLiteOpen : Block : BlockType = 261 \n", 16 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 17 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 18 | "Cannot connect to server socket err = No such file or directory\n", 19 | "Cannot connect to server request channel\n", 20 | "jack server is not running or cannot be started\n", 21 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 22 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 23 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "!cd test1 && python3 pipeline1.py" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "id": "4f5c62e0-6194-4e38-9514-25d117c7c30a", 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "!gst-launch-1.0 playbin uri=file:///dli/task/deepstream/samples/streams/sample_720p.mp4" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 4, 44 | "id": "ebbbe7e7-df04-4d07-9c78-c55febb264a4", 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "\n", 52 | "(python3:492): GStreamer-\u001b[1;33mWARNING\u001b[0m **: \u001b[34m21:12:55.999\u001b[0m: Trying to link elements source and sink that don't share a common ancestor: sink hasn't been added to a bin or pipeline, and source is in test-pipeline\n", 53 | "\n", 54 | "(python3:492): GStreamer-\u001b[1;33mWARNING\u001b[0m **: \u001b[34m21:12:55.999\u001b[0m: Trying to link elements source and sink that don't share a common ancestor: sink hasn't been added to a bin or pipeline, and source is in test-pipeline\n", 55 | "[__main__] [ ERROR] - Elements could not be linked.\n" 56 | ] 57 | } 58 | ], 59 | "source": [ 60 | "!cd test1 && python3 pipeline2.py" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "id": "aea10191-00c6-45ae-b739-659742968fc5", 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [] 70 | } 71 | ], 72 | "metadata": { 73 | "kernelspec": { 74 | "display_name": "Python 3", 75 | "language": "python", 76 | "name": "python3" 77 | }, 78 | "language_info": { 79 | "codemirror_mode": { 80 | "name": "ipython", 81 | "version": 3 82 | }, 83 | "file_extension": ".py", 84 | "mimetype": "text/x-python", 85 | "name": "python", 86 | "nbconvert_exporter": "python", 87 | "pygments_lexer": "ipython3", 88 | "version": "3.6.9" 89 | } 90 | }, 91 | "nbformat": 4, 92 | "nbformat_minor": 5 93 | } 94 | -------------------------------------------------------------------------------- /archive/.ipynb_checkpoints/04-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 3, 6 | "id": "5367f1e9-1543-45d4-849f-a6aad602f596", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "typefindfunctions: application/x-id3v2: mp3, mp2, mp1, mpga, ogg, flac, tta\n", 14 | "typefindfunctions: application/x-id3v1: mp3, mp2, mp1, mpga, ogg, flac, tta\n", 15 | "typefindfunctions: application/x-apetag: mp3, ape, mpc, wv\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "!gst-inspect-1.0 | grep mp3 | head -3" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "id": "e27e0af3-8629-4840-86ad-4a348bea9831", 26 | "metadata": {}, 27 | "source": [ 28 | "## Sink" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 32, 34 | "id": "3a28044f-3b05-413b-b8ec-25dc8060dfb9", 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "name": "stdout", 39 | "output_type": "stream", 40 | "text": [ 41 | "Setting pipeline to PAUSED ...\n", 42 | "Opening in BLOCKING MODE \n", 43 | "Pipeline is PREROLLING ...\n", 44 | "NvMMLiteOpen : Block : BlockType = 261 \n", 45 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 46 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 47 | "Pipeline is PREROLLED ...\n", 48 | "Setting pipeline to PLAYING ...\n", 49 | "New clock: GstSystemClock\n", 50 | "Got EOS from element \"pipeline0\".\n", 51 | "Execution ended after 0:00:48.066789244\n", 52 | "Setting pipeline to PAUSED ...\n", 53 | "Setting pipeline to READY ...\n", 54 | "Setting pipeline to NULL ...\n", 55 | "Freeing pipeline ...\n" 56 | ] 57 | } 58 | ], 59 | "source": [ 60 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.mp4\" ! \\\n", 61 | "qtdemux ! queue ! h264parse ! nvv4l2decoder ! nvoverlaysink -e" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 9, 67 | "id": "3d1f38c9-bf4c-41c7-be56-8fd69579c477", 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "#!gst-inspect-1.0 qtdemux" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 15, 77 | "id": "9169412c-e4ac-43d3-8f10-0ed3af96f439", 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "#!gst-inspect-1.0 queue" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 19, 87 | "id": "e481a6e6-2661-4174-b83e-e6874c625db5", 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "#!gst-inspect-1.0 ! h264parse " 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 20, 97 | "id": "cde248cb-553c-47db-9ba8-595cd7c02d5e", 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "#!gst-inspect-1.0 ! nvv4l2decoder" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 33, 107 | "id": "a49abe12-9504-4add-a10b-b56f0d2fbad1", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "#!gst-inspect-1.0 nvoverlaysink # sink 1" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 34, 117 | "id": "619ffdd1-b646-4706-b974-e41c8202ecd5", 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "#!gst-inspect-1.0 nvvideosink # sink 2" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 39, 127 | "id": "876e5062-3dd7-4450-8377-bfb12be04bee", 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "#!gst-inspect-1.0 appsink # sink 3" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 36, 137 | "id": "41276216-529f-4965-a357-a2ce2d1e4a3f", 138 | "metadata": {}, 139 | "outputs": [ 140 | { 141 | "name": "stdout", 142 | "output_type": "stream", 143 | "text": [ 144 | "Setting pipeline to PAUSED ...\n", 145 | "Opening in BLOCKING MODE \n", 146 | "Pipeline is PREROLLING ...\n", 147 | "NvMMLiteOpen : Block : BlockType = 261 \n", 148 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 149 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 150 | "Pipeline is PREROLLED ...\n", 151 | "Setting pipeline to PLAYING ...\n", 152 | "New clock: GstSystemClock\n", 153 | "Got EOS from element \"pipeline0\".\n", 154 | "Execution ended after 0:00:02.546120419\n", 155 | "Setting pipeline to PAUSED ...\n", 156 | "Setting pipeline to READY ...\n", 157 | "Setting pipeline to NULL ...\n", 158 | "Freeing pipeline ...\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.mp4\" ! \\\n", 164 | "qtdemux ! queue ! h264parse ! nvv4l2decoder ! fakesink -e" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 40, 170 | "id": "fced02ac-61cb-4257-ad97-b5b90ed3e750", 171 | "metadata": {}, 172 | "outputs": [], 173 | "source": [ 174 | "#!gst-inspect-1.0 fakesink # sink 4" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "id": "3f7f56e6-1a6b-4231-b8a5-e911e11fa7e4", 180 | "metadata": {}, 181 | "source": [ 182 | "## Encoder (h264, h256)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 44, 188 | "id": "d09b214d-e126-45b8-9feb-8fcd1cf2ffb9", 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "Setting pipeline to PAUSED ...\n", 196 | "Pipeline is PREROLLING ...\n", 197 | "Framerate set to : 30 at NvxVideoEncoderSetParameterNvMMLiteOpen : Block : BlockType = 4 \n", 198 | "===== NVMEDIA: NVENC =====\n", 199 | "NvMMLiteBlockCreate : Block : BlockType = 4 \n", 200 | "H264: Profile = 66, Level = 40 \n", 201 | "NVMEDIA_ENC: bBlitMode is set to TRUE \n", 202 | "Pipeline is PREROLLED ...\n", 203 | "Setting pipeline to PLAYING ...\n", 204 | "New clock: GstSystemClock\n", 205 | "^C\n", 206 | "handling interrupt.\n", 207 | "Interrupt: Stopping pipeline ...\n", 208 | "Execution ended after 0:01:18.870540722\n", 209 | "Setting pipeline to PAUSED ...\n", 210 | "Setting pipeline to READY ...\n", 211 | "Setting pipeline to NULL ...\n", 212 | "Freeing pipeline ...\n" 213 | ] 214 | } 215 | ], 216 | "source": [ 217 | "!gst-launch-1.0 videotestsrc ! \\\n", 218 | "'video/x-raw, format=(string)I420, width=(int)640, \\\n", 219 | "height=(int)480' ! omxh264enc ! \\\n", 220 | "'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! \\\n", 221 | "qtmux ! filesink location=test.mp4 " 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 49, 227 | "id": "fc158f09-1578-4062-ae6e-aca694bf1c16", 228 | "metadata": {}, 229 | "outputs": [ 230 | { 231 | "name": "stdout", 232 | "output_type": "stream", 233 | "text": [ 234 | "Setting pipeline to PAUSED ...\n", 235 | "Pipeline is PREROLLING ...\n", 236 | "Framerate set to : 30 at NvxVideoEncoderSetParameterNvMMLiteOpen : Block : BlockType = 8 \n", 237 | "===== NVMEDIA: NVENC =====\n", 238 | "NvMMLiteBlockCreate : Block : BlockType = 8 \n", 239 | "NVMEDIA: H265 : Profile : 1 \n", 240 | "NVMEDIA_ENC: bBlitMode is set to TRUE \n", 241 | "Pipeline is PREROLLED ...\n", 242 | "Setting pipeline to PLAYING ...\n", 243 | "New clock: GstSystemClock\n", 244 | "^C\n", 245 | "handling interrupt.\n", 246 | "Interrupt: Stopping pipeline ...\n", 247 | "EOS on shutdown enabled -- Forcing EOS on the pipeline\n", 248 | "Waiting for EOS...\n", 249 | "Got EOS from element \"pipeline0\".\n", 250 | "EOS received - stopping pipeline...\n", 251 | "Execution ended after 0:00:16.869571948\n", 252 | "Setting pipeline to PAUSED ...\n", 253 | "Setting pipeline to READY ...\n", 254 | "Setting pipeline to NULL ...\n", 255 | "Freeing pipeline ...\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "!gst-launch-1.0 videotestsrc ! \\\n", 261 | "'video/x-raw, format=(string)I420, width=(int)640, \\\n", 262 | "height=(int)480' ! omxh265enc ! filesink location=test.h265 -e" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 52, 268 | "id": "03fd6e8f-5621-43ca-96c9-e2200d83f681", 269 | "metadata": {}, 270 | "outputs": [ 271 | { 272 | "name": "stdout", 273 | "output_type": "stream", 274 | "text": [ 275 | "Setting pipeline to PAUSED ...\n", 276 | "Opening in BLOCKING MODE \n", 277 | "Pipeline is live and does not need PREROLL ...\n", 278 | "Setting pipeline to PLAYING ...\n", 279 | "New clock: GstSystemClock\n", 280 | "NvMMLiteOpen : Block : BlockType = 4 \n", 281 | "Redistribute latency...\n", 282 | "===== NVMEDIA: NVENC =====\n", 283 | "Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:740 No cameras available\n", 284 | "NvMMLiteBlockCreate : Block : BlockType = 4 \n", 285 | "Got EOS from element \"pipeline0\".\n", 286 | "Execution ended after 0:00:00.203166178\n", 287 | "Setting pipeline to PAUSED ...\n", 288 | "Setting pipeline to READY ...\n", 289 | "Setting pipeline to NULL ...\n", 290 | "Freeing pipeline ...\n" 291 | ] 292 | } 293 | ], 294 | "source": [ 295 | "!gst-launch-1.0 nvarguscamerasrc ! \\\n", 296 | "'video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, \\\n", 297 | "format=(string)NV12, framerate=(fraction)30/1' ! nvv4l2h264enc \\\n", 298 | "maxperf-enable=1 bitrate=8000000 ! h264parse ! qtmux ! filesink \\\n", 299 | "location=test.mp4 -e" 300 | ] 301 | }, 302 | { 303 | "cell_type": "markdown", 304 | "id": "2458306c-8104-465a-b4b7-3eddf30b6b42", 305 | "metadata": {}, 306 | "source": [ 307 | "## Camera Capture" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 55, 313 | "id": "6d268403-3692-4c5a-97c7-e495f477eac1", 314 | "metadata": {}, 315 | "outputs": [], 316 | "source": [ 317 | "#https://github.com/JetsonHacksNano/CSI-Camera/blob/master/README.md\n", 318 | "#!gst-inspect-1.0 nvarguscamerasrc" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 59, 324 | "id": "e223b32f-4785-4705-b7ed-0430b95e5788", 325 | "metadata": {}, 326 | "outputs": [ 327 | { 328 | "name": "stdout", 329 | "output_type": "stream", 330 | "text": [ 331 | "No such element or plugin 'nvgstcapture'\n" 332 | ] 333 | } 334 | ], 335 | "source": [ 336 | "!gst-inspect-1.0 nvgstcapture" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 64, 342 | "id": "ae0c45bc-95cf-45ac-87ba-3f6979266f43", 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "# !gst-launch-1.0 nvarguscamerasrc ! ‘video/x-raw(memory:NVMM), \\\n", 347 | "# width=(int)1920, height=(int)1080, format=(string)NV12, \\\n", 348 | "# framerate=(fraction)30/1' ! nvoverlaysink -e" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 63, 354 | "id": "f71456f4-240a-4d24-9fa8-f6c3ff786af5", 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "name": "stdout", 359 | "output_type": "stream", 360 | "text": [ 361 | "Setting pipeline to PAUSED ...\n", 362 | "Pipeline is live and does not need PREROLL ...\n", 363 | "Setting pipeline to PLAYING ...\n", 364 | "New clock: GstSystemClock\n", 365 | "^C\n", 366 | "handling interrupt.\n", 367 | "Interrupt: Stopping pipeline ...\n", 368 | "EOS on shutdown enabled -- Forcing EOS on the pipeline\n", 369 | "Waiting for EOS...\n", 370 | "Got EOS from element \"pipeline0\".\n", 371 | "EOS received - stopping pipeline...\n", 372 | "Execution ended after 0:00:16.297610829\n", 373 | "Setting pipeline to PAUSED ...\n", 374 | "Setting pipeline to READY ...\n", 375 | "Setting pipeline to NULL ...\n", 376 | "Freeing pipeline ...\n" 377 | ] 378 | } 379 | ], 380 | "source": [ 381 | "!gst-launch-1.0 v4l2src device=\"/dev/video0\" ! \\\n", 382 | "\"video/x-raw, width=640, height=480, format=(string)YUY2\" ! \\\n", 383 | "xvimagesink -e" 384 | ] 385 | }, 386 | { 387 | "cell_type": "code", 388 | "execution_count": 76, 389 | "id": "69767f4e-577f-4ad0-9b27-1b3e93c69e3c", 390 | "metadata": {}, 391 | "outputs": [ 392 | { 393 | "name": "stdout", 394 | "output_type": "stream", 395 | "text": [ 396 | "Setting pipeline to PAUSED ...\n", 397 | "Opening in BLOCKING MODE \n", 398 | "ERROR: Pipeline doesn't want to pause.\n", 399 | "ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Cannot identify device '/dev/video1'.\n", 400 | "Additional debug info:\n", 401 | "v4l2_calls.c(609): gst_v4l2_open (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:\n", 402 | "system error: No such file or directory\n", 403 | "Setting pipeline to NULL ...\n", 404 | "Freeing pipeline ...\n" 405 | ] 406 | } 407 | ], 408 | "source": [ 409 | "!gst-launch-1.0 v4l2src device=/dev/video1 io-mode=2 ! 'image/jpeg,width=1280,height=720' ! nvv4l2decoder mjpeg=1 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=NV12' ! autovideosink location=tes_image.jpg " 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 8, 415 | "id": "bd3cd26a-7827-4e36-ab5f-f8546d42b24f", 416 | "metadata": {}, 417 | "outputs": [ 418 | { 419 | "name": "stdout", 420 | "output_type": "stream", 421 | "text": [ 422 | "Setting pipeline to PAUSED ...\n", 423 | "Pipeline is live and does not need PREROLL ...\n", 424 | "Setting pipeline to PLAYING ...\n", 425 | "New clock: GstSystemClock\n", 426 | "^C\n", 427 | "handling interrupt.\n", 428 | "Interrupt: Stopping pipeline ...\n", 429 | "Execution ended after 0:00:02.999759293\n", 430 | "Setting pipeline to PAUSED ...\n", 431 | "Setting pipeline to READY ...\n", 432 | "Setting pipeline to NULL ...\n", 433 | "Freeing pipeline ...\n" 434 | ] 435 | } 436 | ], 437 | "source": [ 438 | "!gst-launch-1.0 v4l2src device=/dev/video0 ! \"video/x-raw, format=YUY2, width=640, height=480, pixel-aspect-ratio=1/1, framerate=30/1\" ! videoconvert ! appsink" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": 72, 444 | "id": "4a774f2d-b719-4ce3-91c9-21b253699891", 445 | "metadata": {}, 446 | "outputs": [ 447 | { 448 | "name": "stdout", 449 | "output_type": "stream", 450 | "text": [ 451 | "Factory Details:\n", 452 | " Rank none (0)\n", 453 | " Long-name Auto video sink\n", 454 | " Klass Sink/Video\n", 455 | " Description Wrapper video sink for automatically detected video sink\n", 456 | " Author Jan Schmidt \n", 457 | "\n", 458 | "Plugin Details:\n", 459 | " Name autodetect\n", 460 | " Description Plugin contains auto-detection plugins for video/audio in- and outputs\n", 461 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstautodetect.so\n", 462 | " Version 1.14.5\n", 463 | " License LGPL\n", 464 | " Source module gst-plugins-good\n", 465 | " Source release date 2019-05-29\n", 466 | " Binary package GStreamer Good Plugins (Ubuntu)\n", 467 | " Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-good1.0\n", 468 | "\n", 469 | "GObject\n", 470 | " +----GInitiallyUnowned\n", 471 | " +----GstObject\n", 472 | " +----GstElement\n", 473 | " +----GstBin\n", 474 | " +----GstAutoDetect\n", 475 | " +----GstAutoVideoSink\n", 476 | "\n", 477 | "Implemented Interfaces:\n", 478 | " GstChildProxy\n", 479 | "\n", 480 | "Pad Templates:\n", 481 | " SINK template: 'sink'\n", 482 | " Availability: Always\n", 483 | " Capabilities:\n", 484 | " ANY\n", 485 | "\n", 486 | "Element has no clocking capabilities.\n", 487 | "Element has no URI handling capabilities.\n", 488 | "\n", 489 | "Pads:\n", 490 | " SINK: 'sink'\n", 491 | "\n", 492 | "Element Properties:\n", 493 | " name : The name of the object\n", 494 | " flags: readable, writable\n", 495 | " String. Default: \"autovideosink0\"\n", 496 | " parent : The parent of the object\n", 497 | " flags: readable, writable\n", 498 | " Object of type \"GstObject\"\n", 499 | " async-handling : The bin will handle Asynchronous state changes\n", 500 | " flags: readable, writable\n", 501 | " Boolean. Default: false\n", 502 | " message-forward : Forwards all children messages\n", 503 | " flags: readable, writable\n", 504 | " Boolean. Default: false\n", 505 | " filter-caps : Filter sink candidates using these caps.\n", 506 | " flags: readable, writable\n", 507 | " video/x-raw\n", 508 | "\n", 509 | " sync : Sync on the clock\n", 510 | " flags: readable, writable\n", 511 | " Boolean. Default: true\n", 512 | " ts-offset : Timestamp offset in nanoseconds\n", 513 | " flags: readable, writable\n", 514 | " Integer64. Range: -9223372036854775808 - 9223372036854775807 Default: 0 \n", 515 | "\n", 516 | "Children:\n", 517 | " fake-video-sink\n" 518 | ] 519 | } 520 | ], 521 | "source": [ 522 | "!gst-inspect-1.0 autovideosink" 523 | ] 524 | }, 525 | { 526 | "cell_type": "markdown", 527 | "id": "0980cafd-fb65-4ef3-a951-7c83f267b229", 528 | "metadata": { 529 | "tags": [] 530 | }, 531 | "source": [ 532 | "## Decoder " 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": null, 538 | "id": "81a1ddc7-5931-4d10-bb57-14558ca5f63f", 539 | "metadata": {}, 540 | "outputs": [], 541 | "source": [ 542 | "# try nvv4l2decoder\n", 543 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.h264\" ! h264parse ! nvv4l2decoder ! videoconvert ! autovideosink" 544 | ] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "execution_count": 19, 549 | "id": "396cf22d-f34d-4cd0-b12b-6cb21ecd525c", 550 | "metadata": {}, 551 | "outputs": [ 552 | { 553 | "name": "stdout", 554 | "output_type": "stream", 555 | "text": [ 556 | "Factory Details:\n", 557 | " Rank primary + 11 (267)\n", 558 | " Long-name NVIDIA v4l2 video decoder\n", 559 | " Klass Codec/Decoder/Video\n", 560 | " Description Decode video streams via V4L2 API\n", 561 | " Author Nicolas Dufresne , Viranjan Pagar \n", 562 | "\n", 563 | "Plugin Details:\n", 564 | " Name nvvideo4linux2\n", 565 | " Description Nvidia elements for Video 4 Linux\n", 566 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvvideo4linux2.so\n", 567 | " Version 1.14.0\n", 568 | " License LGPL\n", 569 | " Source module nvvideo4linux2\n", 570 | " Binary package nvvideo4linux2\n", 571 | " Origin URL http://nvidia.com/\n", 572 | "\n", 573 | "GObject\n", 574 | " +----GInitiallyUnowned\n", 575 | " +----GstObject\n", 576 | " +----GstElement\n", 577 | " +----GstVideoDecoder\n", 578 | " +----GstNvV4l2VideoDec\n", 579 | " +----nvv4l2decoder\n", 580 | "\n", 581 | "Pad Templates:\n", 582 | " SRC template: 'src'\n", 583 | " Availability: Always\n", 584 | " Capabilities:\n", 585 | " video/x-raw(memory:NVMM)\n", 586 | " width: [ 1, 2147483647 ]\n", 587 | " height: [ 1, 2147483647 ]\n", 588 | " framerate: [ 0/1, 2147483647/1 ]\n", 589 | " \n", 590 | " SINK template: 'sink'\n", 591 | " Availability: Always\n", 592 | " Capabilities:\n", 593 | " image/jpeg\n", 594 | " video/x-h264\n", 595 | " stream-format: { (string)byte-stream }\n", 596 | " alignment: { (string)au }\n", 597 | " video/x-h265\n", 598 | " stream-format: { (string)byte-stream }\n", 599 | " alignment: { (string)au }\n", 600 | " video/mpeg\n", 601 | " mpegversion: 4\n", 602 | " systemstream: false\n", 603 | " parsed: true\n", 604 | " width: [ 1, 2147483647 ]\n", 605 | " height: [ 1, 2147483647 ]\n", 606 | " video/mpeg\n", 607 | " mpegversion: [ 1, 2 ]\n", 608 | " systemstream: false\n", 609 | " parsed: true\n", 610 | " width: [ 1, 2147483647 ]\n", 611 | " height: [ 1, 2147483647 ]\n", 612 | " video/x-divx\n", 613 | " divxversion: [ 4, 5 ]\n", 614 | " width: [ 1, 2147483647 ]\n", 615 | " height: [ 1, 2147483647 ]\n", 616 | " video/x-vp8\n", 617 | " video/x-vp9\n", 618 | " width: [ 1, 2147483647 ]\n", 619 | " height: [ 1, 2147483647 ]\n", 620 | "\n", 621 | "Element has no clocking capabilities.\n", 622 | "Element has no URI handling capabilities.\n", 623 | "\n", 624 | "Pads:\n", 625 | " SINK: 'sink'\n", 626 | " Pad Template: 'sink'\n", 627 | " SRC: 'src'\n", 628 | " Pad Template: 'src'\n", 629 | "\n", 630 | "Element Properties:\n", 631 | " name : The name of the object\n", 632 | " flags: readable, writable\n", 633 | " String. Default: \"nvv4l2decoder0\"\n", 634 | " parent : The parent of the object\n", 635 | " flags: readable, writable\n", 636 | " Object of type \"GstObject\"\n", 637 | " device : Device location\n", 638 | " flags: readable\n", 639 | " String. Default: \"/dev/nvhost-nvdec\"\n", 640 | " device-name : Name of the device\n", 641 | " flags: Opening in BLOCKING MODE \n", 642 | "readable\n", 643 | " String. Default: \"\"\n", 644 | " device-fd : File descriptor of the device\n", 645 | " flags: readable\n", 646 | " Integer. Range: -1 - 2147483647 Default: -1 \n", 647 | " output-io-mode : Output side I/O mode (matches sink pad)\n", 648 | " flags: readable, writable\n", 649 | " Enum \"GstNvV4l2DecOutputIOMode\" Default: 0, \"auto\"\n", 650 | " (0): auto - GST_V4L2_IO_AUTO\n", 651 | " (2): mmap - GST_V4L2_IO_MMAP\n", 652 | " (3): userptr - GST_V4L2_IO_USERPTR\n", 653 | " capture-io-mode : Capture I/O mode (matches src pad)\n", 654 | " flags: readable, writable\n", 655 | " Enum \"GstNvV4l2DecCaptureIOMode\" Default: 0, \"auto\"\n", 656 | " (0): auto - GST_V4L2_IO_AUTO\n", 657 | " (2): mmap - GST_V4L2_IO_MMAP\n", 658 | " extra-controls : Extra v4l2 controls (CIDs) for the device\n", 659 | " flags: readable, writable\n", 660 | " Boxed pointer of type \"GstStructure\"\n", 661 | " skip-frames : Type of frames to skip during decoding\n", 662 | " flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state\n", 663 | " Enum \"SkipFrame\" Default: 0, \"decode_all\"\n", 664 | " (0): decode_all - Decode all frames\n", 665 | " (1): decode_non_ref - Decode non-ref frames\n", 666 | " (2): decode_key - decode key frames\n", 667 | " drop-frame-interval : Interval to drop the frames,ex: value of 5 means every 5th frame will be given by decoder, rest all dropped\n", 668 | " flags: readable, writable, changeable only in NULL or READY state\n", 669 | " Unsigned Integer. Range: 0 - 30 Default: 0 \n", 670 | " num-extra-surfaces : Additional number of surfaces in addition to min decode surfaces given by the v4l2 driver\n", 671 | " flags: readable, writable, changeable only in NULL or READY state\n", 672 | " Unsigned Integer. Range: 0 - 55 Default: 1 \n", 673 | " disable-dpb : Set to disable DPB buffer for low latency\n", 674 | " flags: readable, writable\n", 675 | " Boolean. Default: false\n", 676 | " enable-full-frame : Whether or not the data is full framed\n", 677 | " flags: readable, writable\n", 678 | " Boolean. Default: false\n", 679 | " enable-frame-type-reporting: Set to enable frame type reporting\n", 680 | " flags: readable, writable\n", 681 | " Boolean. Default: false\n", 682 | " enable-error-check : Set to enable error check\n", 683 | " flags: readable, writable\n", 684 | " Boolean. Default: false\n", 685 | " enable-max-performance: Set to enable max performance\n", 686 | " flags: readable, writable\n", 687 | " Boolean. Default: false\n", 688 | " mjpeg : Set to open MJPEG block\n", 689 | " flags: readable, writable\n", 690 | " Boolean. Default: false\n", 691 | " bufapi-version : Set to use new buf API\n", 692 | " flags: readable, writable\n", 693 | " Boolean. Default: false\n", 694 | " capture-buffer-dynamic-allocation: Set to enable capture buffer dynamic allocation\n", 695 | " flags: readable, writable\n", 696 | " Enum \"CaptureBufferDynamicAllocationModes\" Default: 0, \"cap_buf_dyn_alloc_disabled\"\n", 697 | " (0): cap_buf_dyn_alloc_disabled - Capture buffer dynamic allocation disabled\n", 698 | " (1): fw_cap_buf_dyn_alloc_enabled - Capture buffer dynamic allocation enabled for forward playback\n", 699 | " (2): rw_cap_buf_dyn_alloc_enabled - Capture buffer dynamic allocation enabled for reverse playback\n", 700 | " (3): fw_rw_cap_buf_dyn_alloc_enabled - Capture buffer dynamic allocation enabled for forward and reverse playback\n" 701 | ] 702 | } 703 | ], 704 | "source": [ 705 | "!gst-inspect-1.0 nvv4l2decoder" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "execution_count": null, 711 | "id": "f9de295c-2a5e-462c-98c8-404a00ee54c2", 712 | "metadata": {}, 713 | "outputs": [], 714 | "source": [ 715 | "!ls /dli/task/deepstream/samples/streams/ #try another source file " 716 | ] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "execution_count": 13, 721 | "id": "001c38c6-f354-4a69-ac97-a65990f96914", 722 | "metadata": {}, 723 | "outputs": [ 724 | { 725 | "name": "stdout", 726 | "output_type": "stream", 727 | "text": [ 728 | "Setting pipeline to PAUSED ...\n", 729 | "Pipeline is PREROLLING ...\n", 730 | "Opening in BLOCKING MODE \n", 731 | "NvMMLiteOpen : Block : BlockType = 261 \n", 732 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 733 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 734 | "Pipeline is PREROLLED ...\n", 735 | "Setting pipeline to PLAYING ...\n", 736 | "New clock: GstSystemClock\n", 737 | "Got EOS from element \"pipeline0\".\n", 738 | "Execution ended after 0:00:48.066525862\n", 739 | "Setting pipeline to PAUSED ...\n", 740 | "Setting pipeline to READY ...\n", 741 | "Setting pipeline to NULL ...\n", 742 | "Freeing pipeline ...\n" 743 | ] 744 | } 745 | ], 746 | "source": [ 747 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.h264\" ! h264parse ! decodebin ! videoconvert ! autovideosink" 748 | ] 749 | }, 750 | { 751 | "cell_type": "code", 752 | "execution_count": 20, 753 | "id": "85703b68-3aca-4f87-9734-2be2f74fb5e3", 754 | "metadata": {}, 755 | "outputs": [ 756 | { 757 | "name": "stdout", 758 | "output_type": "stream", 759 | "text": [ 760 | "Factory Details:\n", 761 | " Rank none (0)\n", 762 | " Long-name Decoder Bin\n", 763 | " Klass Generic/Bin/Decoder\n", 764 | " Description Autoplug and decode to raw media\n", 765 | " Author Edward Hervey , Sebastian Dr��ge \n", 766 | "\n", 767 | "Plugin Details:\n", 768 | " Name playback\n", 769 | " Description various playback elements\n", 770 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstplayback.so\n", 771 | " Version 1.14.5\n", 772 | " License LGPL\n", 773 | " Source module gst-plugins-base\n", 774 | " Source release date 2019-05-29\n", 775 | " Binary package GStreamer Base Plugins (Ubuntu)\n", 776 | " Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-base1.0\n", 777 | "\n", 778 | "GObject\n", 779 | " +----GInitiallyUnowned\n", 780 | " +----GstObject\n", 781 | " +----GstElement\n", 782 | " +----GstBin\n", 783 | " +----GstDecodeBin\n", 784 | "\n", 785 | "Implemented Interfaces:\n", 786 | " GstChildProxy\n", 787 | "\n", 788 | "Pad Templates:\n", 789 | " SINK template: 'sink'\n", 790 | " Availability: Always\n", 791 | " Capabilities:\n", 792 | " ANY\n", 793 | " \n", 794 | " SRC template: 'src_%u'\n", 795 | " Availability: Sometimes\n", 796 | " Capabilities:\n", 797 | " ANY\n", 798 | "\n", 799 | "Element has no clocking capabilities.\n", 800 | "Element has no URI handling capabilities.\n", 801 | "\n", 802 | "Pads:\n", 803 | " SINK: 'sink'\n", 804 | " Pad Template: 'sink'\n", 805 | "\n", 806 | "Element Properties:\n", 807 | " name : The name of the object\n", 808 | " flags: readable, writable\n", 809 | " String. Default: \"decodebin0\"\n", 810 | " parent : The parent of the object\n", 811 | " flags: readable, writable\n", 812 | " Object of type \"GstObject\"\n", 813 | " async-handling : The bin will handle Asynchronous state changes\n", 814 | " flags: readable, writable\n", 815 | " Boolean. Default: false\n", 816 | " message-forward : Forwards all children messages\n", 817 | " flags: readable, writable\n", 818 | " Boolean. Default: false\n", 819 | " caps : The caps on which to stop decoding.\n", 820 | " flags: readable, writable\n", 821 | " video/x-raw(ANY)\n", 822 | " audio/x-raw(ANY)\n", 823 | " text/x-raw(ANY)\n", 824 | " subpicture/x-dvd\n", 825 | " subpicture/x-dvb\n", 826 | " subpicture/x-xsub\n", 827 | " subpicture/x-pgs\n", 828 | "\n", 829 | " subtitle-encoding : Encoding to assume if input subtitles are not in UTF-8 encoding. If not set, the GST_SUBTITLE_ENCODING environment variable will be checked for an encoding to use. If that is not set either, ISO-8859-15 will be assumed.\n", 830 | " flags: readable, writable\n", 831 | " String. Default: null\n", 832 | " sink-caps : The caps of the input data. (NULL = use typefind element)\n", 833 | " flags: readable, writable\n", 834 | " Caps (NULL)\n", 835 | " use-buffering : Emit GST_MESSAGE_BUFFERING based on low-/high-percent thresholds\n", 836 | " flags: readable, writable\n", 837 | " Boolean. Default: false\n", 838 | " low-percent : Low threshold for buffering to start\n", 839 | " flags: readable, writable\n", 840 | " Integer. Range: 0 - 100 Default: 10 \n", 841 | " high-percent : High threshold for buffering to finish\n", 842 | " flags: readable, writable\n", 843 | " Integer. Range: 0 - 100 Default: 99 \n", 844 | " max-size-bytes : Max. amount of bytes in the queue (0=automatic)\n", 845 | " flags: readable, writable\n", 846 | " Unsigned Integer. Range: 0 - 4294967295 Default: 0 \n", 847 | " max-size-buffers : Max. number of buffers in the queue (0=automatic)\n", 848 | " flags: readable, writable\n", 849 | " Unsigned Integer. Range: 0 - 4294967295 Default: 0 \n", 850 | " max-size-time : Max. amount of data in the queue (in ns, 0=automatic)\n", 851 | " flags: readable, writable\n", 852 | " Unsigned Integer64. Range: 0 - 18446744073709551615 Default: 0 \n", 853 | " post-stream-topology: Post stream-topology messages\n", 854 | " flags: readable, writable\n", 855 | " Boolean. Default: false\n", 856 | " expose-all-streams : Expose all streams, including those of unknown type or that don't match the 'caps' property\n", 857 | " flags: readable, writable\n", 858 | " Boolean. Default: true\n", 859 | " connection-speed : Network connection speed in kbps (0 = unknown)\n", 860 | " flags: readable, writable\n", 861 | " Unsigned Integer64. Range: 0 - 18446744073709551 Default: 0 \n", 862 | "\n", 863 | "Element Signals:\n", 864 | " \"pad-added\" : void user_function (GstElement* object,\n", 865 | " GstPad* arg0,\n", 866 | " gpointer user_data);\n", 867 | " \"pad-removed\" : void user_function (GstElement* object,\n", 868 | " GstPad* arg0,\n", 869 | " gpointer user_data);\n", 870 | " \"no-more-pads\" : void user_function (GstElement* object,\n", 871 | " gpointer user_data);\n", 872 | " \"unknown-type\" : void user_function (GstElement* object,\n", 873 | " GstPad* arg0,\n", 874 | " GstCaps* arg1,\n", 875 | " gpointer user_data);\n", 876 | " \"autoplug-continue\" : gboolean user_function (GstElement* object,\n", 877 | " GstPad* arg0,\n", 878 | " GstCaps* arg1,\n", 879 | " gpointer user_data);\n", 880 | " \"autoplug-factories\" : GValueArray * user_function (GstElement* object,\n", 881 | " GstPad* arg0,\n", 882 | " GstCaps* arg1,\n", 883 | " gpointer user_data);\n", 884 | " \"autoplug-sort\" : GValueArray * user_function (GstElement* object,\n", 885 | " GstPad* arg0,\n", 886 | " GstCaps* arg1,\n", 887 | " GValueArray* arg2,\n", 888 | " gpointer user_data);\n", 889 | " \"autoplug-select\" : GstAutoplugSelectResult user_function (GstElement* object,\n", 890 | " GstPad* arg0,\n", 891 | " GstCaps* arg1,\n", 892 | " GstElementFactory* arg2,\n", 893 | " gpointer user_data);\n", 894 | " \"autoplug-query\" : gboolean user_function (GstElement* object,\n", 895 | " GstPad* arg0,\n", 896 | " GstElement* arg1,\n", 897 | " GstQuery* arg2,\n", 898 | " gpointer user_data);\n", 899 | " \"drained\" : void user_function (GstElement* object,\n", 900 | " gpointer user_data);\n", 901 | "\n", 902 | "Children:\n", 903 | " typefind\n" 904 | ] 905 | } 906 | ], 907 | "source": [ 908 | "!gst-inspect-1.0 decodebin " 909 | ] 910 | }, 911 | { 912 | "cell_type": "markdown", 913 | "id": "b883527f-e70b-4bd9-bd79-33975083b72d", 914 | "metadata": {}, 915 | "source": [ 916 | "## Parser H264 and H265" 917 | ] 918 | }, 919 | { 920 | "cell_type": "code", 921 | "execution_count": null, 922 | "id": "7138d6c1-13b7-470e-8e42-03f8fedaba5e", 923 | "metadata": {}, 924 | "outputs": [ 925 | { 926 | "name": "stdout", 927 | "output_type": "stream", 928 | "text": [ 929 | "Setting pipeline to PAUSED ...\n", 930 | "Opening in BLOCKING MODE \n", 931 | "Pipeline is PREROLLING ...\n", 932 | "ERROR: from element /GstPipeline:pipeline0/GstH264Parse:h264parse0: Internal data stream error.\n", 933 | "Additional debug info:\n", 934 | "gstbaseparse.c(3611): gst_base_parse_loop (): /GstPipeline:pipeline0/GstH264Parse:h264parse0:\n", 935 | "streaming stopped, reason not-negotiated (-4)\n", 936 | "ERROR: pipeline doesn't want to preroll.\n", 937 | "Setting pipeline to NULL ...\n", 938 | "Freeing pipeline ...\n" 939 | ] 940 | } 941 | ], 942 | "source": [ 943 | "# try nvv4l2decoder\n", 944 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.h264\" ! h264parse ! nvv4l2decoder ! videoconvert ! autovideosink" 945 | ] 946 | }, 947 | { 948 | "cell_type": "code", 949 | "execution_count": 21, 950 | "id": "277c91d5-5266-45bd-970a-97cc303c54ce", 951 | "metadata": {}, 952 | "outputs": [ 953 | { 954 | "name": "stdout", 955 | "output_type": "stream", 956 | "text": [ 957 | "Factory Details:\n", 958 | " Rank primary + 1 (257)\n", 959 | " Long-name H.264 parser\n", 960 | " Klass Codec/Parser/Converter/Video\n", 961 | " Description Parses H.264 streams\n", 962 | " Author Mark Nauwelaerts \n", 963 | "\n", 964 | "Plugin Details:\n", 965 | " Name videoparsersbad\n", 966 | " Description videoparsers\n", 967 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstvideoparsersbad.so\n", 968 | " Version 1.14.5\n", 969 | " License LGPL\n", 970 | " Source module gst-plugins-bad\n", 971 | " Source release date 2019-05-29\n", 972 | " Binary package GStreamer Bad Plugins (Ubuntu)\n", 973 | " Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-bad1.0\n", 974 | "\n", 975 | "GObject\n", 976 | " +----GInitiallyUnowned\n", 977 | " +----GstObject\n", 978 | " +----GstElement\n", 979 | " +----GstBaseParse\n", 980 | " +----GstH264Parse\n", 981 | "\n", 982 | "Pad Templates:\n", 983 | " SRC template: 'src'\n", 984 | " Availability: Always\n", 985 | " Capabilities:\n", 986 | " video/x-h264\n", 987 | " parsed: true\n", 988 | " stream-format: { (string)avc, (string)avc3, (string)byte-stream }\n", 989 | " alignment: { (string)au, (string)nal }\n", 990 | " \n", 991 | " SINK template: 'sink'\n", 992 | " Availability: Always\n", 993 | " Capabilities:\n", 994 | " video/x-h264\n", 995 | "\n", 996 | "Element has no clocking capabilities.\n", 997 | "Element has no URI handling capabilities.\n", 998 | "\n", 999 | "Pads:\n", 1000 | " SINK: 'sink'\n", 1001 | " Pad Template: 'sink'\n", 1002 | " SRC: 'src'\n", 1003 | " Pad Template: 'src'\n", 1004 | "\n", 1005 | "Element Properties:\n", 1006 | " name : The name of the object\n", 1007 | " flags: readable, writable\n", 1008 | " String. Default: \"h264parse0\"\n", 1009 | " parent : The parent of the object\n", 1010 | " flags: readable, writable\n", 1011 | " Object of type \"GstObject\"\n", 1012 | " disable-passthrough : Force processing (disables passthrough)\n", 1013 | " flags: readable, writable\n", 1014 | " Boolean. Default: false\n", 1015 | " config-interval : Send SPS and PPS Insertion Interval in seconds (sprop parameter sets will be multiplexed in the data stream when detected.) (0 = disabled, -1 = send with every IDR frame)\n", 1016 | " flags: readable, writable\n", 1017 | " Integer. Range: -1 - 3600 Default: 0 \n" 1018 | ] 1019 | } 1020 | ], 1021 | "source": [ 1022 | "!gst-inspect-1.0 h264parse" 1023 | ] 1024 | }, 1025 | { 1026 | "cell_type": "code", 1027 | "execution_count": null, 1028 | "id": "96e519ed-ee78-490c-a7d0-5fc616855b14", 1029 | "metadata": {}, 1030 | "outputs": [ 1031 | { 1032 | "name": "stdout", 1033 | "output_type": "stream", 1034 | "text": [ 1035 | "sample_1080p_h264.mp4 sample_720p.mp4\t sample_qHD.mp4\t yoga.jpg\n", 1036 | "sample_1080p_h265.mp4 sample_cam6.mp4\t sample_ride_bike.mov yoga.mp4\n", 1037 | "sample_720p.h264 sample_industrial.jpg sample_run.mov\n", 1038 | "sample_720p.jpg sample_push.mov\t sample_walk.mov\n", 1039 | "sample_720p.mjpeg sample_qHD.h264\t sonyc_mixed_audio.wav\n" 1040 | ] 1041 | } 1042 | ], 1043 | "source": [ 1044 | "!ls /dli/task/deepstream/samples/streams/ #try another source file " 1045 | ] 1046 | }, 1047 | { 1048 | "cell_type": "code", 1049 | "execution_count": 24, 1050 | "id": "11a61700-d439-445a-9978-664af616f8ad", 1051 | "metadata": {}, 1052 | "outputs": [], 1053 | "source": [ 1054 | "# try h265\n", 1055 | "#!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_1080p_h265.mp4\" ! h265parse ! nvv4l2decoder ! videoconvert ! autovideosink" 1056 | ] 1057 | }, 1058 | { 1059 | "cell_type": "markdown", 1060 | "id": "a9cac5c6-d0c4-4a14-b41a-501fa7cd9c81", 1061 | "metadata": {}, 1062 | "source": [ 1063 | "## Video Converter " 1064 | ] 1065 | }, 1066 | { 1067 | "cell_type": "code", 1068 | "execution_count": null, 1069 | "id": "7b33e82c-ab65-4fad-847f-5235b32023a5", 1070 | "metadata": {}, 1071 | "outputs": [], 1072 | "source": [ 1073 | "# try nvv4l2decoder\n", 1074 | "!gst-launch-1.0 filesrc location=\"/dli/task/deepstream/samples/streams/sample_720p.h264\" ! h264parse ! nvv4l2decoder ! videoconvert ! autovideosink" 1075 | ] 1076 | }, 1077 | { 1078 | "cell_type": "code", 1079 | "execution_count": 26, 1080 | "id": "0d08f4df-29bd-4a79-ad44-ce36be006ae6", 1081 | "metadata": {}, 1082 | "outputs": [], 1083 | "source": [ 1084 | "#!gst-inspect-1.0 videoconvert" 1085 | ] 1086 | }, 1087 | { 1088 | "cell_type": "markdown", 1089 | "id": "9f6b3e37-4201-4367-b5e9-38547380615e", 1090 | "metadata": {}, 1091 | "source": [ 1092 | "## Muxer " 1093 | ] 1094 | }, 1095 | { 1096 | "cell_type": "code", 1097 | "execution_count": null, 1098 | "id": "de59036a-913e-4c01-a176-ccda3a5525c0", 1099 | "metadata": {}, 1100 | "outputs": [], 1101 | "source": [ 1102 | "#!gst-inspect-1.0 nvstreammux" 1103 | ] 1104 | }, 1105 | { 1106 | "cell_type": "markdown", 1107 | "id": "6fe2e78a-7b98-42c8-9142-a762f6c72dc2", 1108 | "metadata": {}, 1109 | "source": [ 1110 | "## Demuxer " 1111 | ] 1112 | }, 1113 | { 1114 | "cell_type": "code", 1115 | "execution_count": 27, 1116 | "id": "b3c77b86-9e2e-4593-9e8d-eb239e20af2b", 1117 | "metadata": {}, 1118 | "outputs": [ 1119 | { 1120 | "name": "stdout", 1121 | "output_type": "stream", 1122 | "text": [ 1123 | "Factory Details:\n", 1124 | " Rank primary (256)\n", 1125 | " Long-name QuickTime demuxer\n", 1126 | " Klass Codec/Demuxer\n", 1127 | " Description Demultiplex a QuickTime file into audio and video streams\n", 1128 | " Author David Schleef , Wim Taymans \n", 1129 | "\n", 1130 | "Plugin Details:\n", 1131 | " Name isomp4\n", 1132 | " Description ISO base media file format support (mp4, 3gpp, qt, mj2)\n", 1133 | " Filename /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstisomp4.so\n", 1134 | " Version 1.14.5\n", 1135 | " License LGPL\n", 1136 | " Source module gst-plugins-good\n", 1137 | " Source release date 2019-05-29\n", 1138 | " Binary package GStreamer Good Plugins (Ubuntu)\n", 1139 | " Origin URL https://launchpad.net/distros/ubuntu/+source/gst-plugins-good1.0\n", 1140 | "\n", 1141 | "GObject\n", 1142 | " +----GInitiallyUnowned\n", 1143 | " +----GstObject\n", 1144 | " +----GstElement\n", 1145 | " +----GstQTDemux\n", 1146 | "\n", 1147 | "Pad Templates:\n", 1148 | " SINK template: 'sink'\n", 1149 | " Availability: Always\n", 1150 | " Capabilities:\n", 1151 | " video/quicktime\n", 1152 | " video/mj2\n", 1153 | " audio/x-m4a\n", 1154 | " application/x-3gp\n", 1155 | " \n", 1156 | " SRC template: 'video_%u'\n", 1157 | " Availability: Sometimes\n", 1158 | " Capabilities:\n", 1159 | " ANY\n", 1160 | " \n", 1161 | " SRC template: 'audio_%u'\n", 1162 | " Availability: Sometimes\n", 1163 | " Capabilities:\n", 1164 | " ANY\n", 1165 | " \n", 1166 | " SRC template: 'subtitle_%u'\n", 1167 | " Availability: Sometimes\n", 1168 | " Capabilities:\n", 1169 | " ANY\n", 1170 | "\n", 1171 | "Element has no clocking capabilities.\n", 1172 | "Element has no URI handling capabilities.\n", 1173 | "\n", 1174 | "Pads:\n", 1175 | " SINK: 'sink'\n", 1176 | " Pad Template: 'sink'\n", 1177 | "\n", 1178 | "Element Properties:\n", 1179 | " name : The name of the object\n", 1180 | " flags: readable, writable\n", 1181 | " String. Default: \"qtdemux0\"\n", 1182 | " parent : The parent of the object\n", 1183 | " flags: readable, writable\n", 1184 | " Object of type \"GstObject\"\n", 1185 | "\n", 1186 | "Element Signals:\n", 1187 | " \"pad-added\" : void user_function (GstElement* object,\n", 1188 | " GstPad* arg0,\n", 1189 | " gpointer user_data);\n", 1190 | " \"pad-removed\" : void user_function (GstElement* object,\n", 1191 | " GstPad* arg0,\n", 1192 | " gpointer user_data);\n", 1193 | " \"no-more-pads\" : void user_function (GstElement* object,\n", 1194 | " gpointer user_data);\n" 1195 | ] 1196 | } 1197 | ], 1198 | "source": [ 1199 | "#!gst-inspect-1.0 qtdemux" 1200 | ] 1201 | }, 1202 | { 1203 | "cell_type": "code", 1204 | "execution_count": null, 1205 | "id": "7af2cb29-4b7c-4239-ae60-c44fe2d2e871", 1206 | "metadata": {}, 1207 | "outputs": [], 1208 | "source": [] 1209 | } 1210 | ], 1211 | "metadata": { 1212 | "kernelspec": { 1213 | "display_name": "Python 3", 1214 | "language": "python", 1215 | "name": "python3" 1216 | }, 1217 | "language_info": { 1218 | "codemirror_mode": { 1219 | "name": "ipython", 1220 | "version": 3 1221 | }, 1222 | "file_extension": ".py", 1223 | "mimetype": "text/x-python", 1224 | "name": "python", 1225 | "nbconvert_exporter": "python", 1226 | "pygments_lexer": "ipython3", 1227 | "version": "3.6.9" 1228 | } 1229 | }, 1230 | "nbformat": 4, 1231 | "nbformat_minor": 5 1232 | } 1233 | -------------------------------------------------------------------------------- /archive/03.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e687d9ec", 6 | "metadata": {}, 7 | "source": [ 8 | "## Introduction to Pipline" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "7eb36929-30b8-4ee2-ae83-26de93edcbc0", 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n", 22 | "Opening in BLOCKING MODE \n", 23 | "NvMMLiteOpen : Block : BlockType = 261 \n", 24 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 25 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 26 | "Cannot connect to server socket err = No such file or directory\n", 27 | "Cannot connect to server request channel\n", 28 | "jack server is not running or cannot be started\n", 29 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 30 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 31 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "!cd test1 && python3 pipeline1.py" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "id": "4f5c62e0-6194-4e38-9514-25d117c7c30a", 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "name": "stdout", 47 | "output_type": "stream", 48 | "text": [ 49 | "Setting pipeline to PAUSED ...\n", 50 | "Pipeline is PREROLLING ...\n", 51 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n", 52 | "Opening in BLOCKING MODE \n", 53 | "NvMMLiteOpen : Block : BlockType = 261 \n", 54 | "NVMEDIA: Reading vendor.tegra.display-size : status: 6 \n", 55 | "NvMMLiteBlockCreate : Block : BlockType = 261 \n", 56 | "Cannot connect to server socket err = No such file or directory\n", 57 | "Cannot connect to server request channel\n", 58 | "jack server is not running or cannot be started\n", 59 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 60 | "JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock\n", 61 | "AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory\n", 62 | "Pipeline is PREROLLED ...\n", 63 | "Setting pipeline to PLAYING ...\n", 64 | "New clock: GstSystemClock\n", 65 | "Got EOS from element \"playbin0\".\n", 66 | "Execution ended after 0:00:48.067101244\n", 67 | "Setting pipeline to PAUSED ...\n", 68 | "Setting pipeline to READY ...\n", 69 | "Setting pipeline to NULL ...\n", 70 | "Freeing pipeline ...\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "!gst-launch-1.0 playbin uri=file:///dli/task/deepstream/samples/streams/sample_720p.mp4" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 4, 81 | "id": "ebbbe7e7-df04-4d07-9c78-c55febb264a4", 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "Traceback (most recent call last):\n", 89 | " File \"pipeline2.py\", line 25, in \n", 90 | " pipeline.add(source, sink)\n", 91 | "TypeError: Gst.Bin.add() takes exactly 2 arguments (3 given)\n" 92 | ] 93 | } 94 | ], 95 | "source": [ 96 | "!cd test1 && python3 pipeline2.py" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 2, 102 | "id": "aea10191-00c6-45ae-b739-659742968fc5", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "!cd test1 && python3 pipeline5.py" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "id": "851d108e-6e11-49f4-a951-6417b41b7bcd", 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.6.9" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 5 139 | } 140 | -------------------------------------------------------------------------------- /archive/05.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Visualizing Gstreamer Element " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "# Install Flatpak and GstPipelineStudio\n", 17 | "# https://flatpak.org/setup/Ubuntu\n", 18 | "# https://flathub.org/apps/details/org.freedesktop.dabrain34.GstPipelineStudio" 19 | ] 20 | } 21 | ], 22 | "metadata": { 23 | "language_info": { 24 | "name": "python" 25 | }, 26 | "orig_nbformat": 4 27 | }, 28 | "nbformat": 4, 29 | "nbformat_minor": 2 30 | } 31 | -------------------------------------------------------------------------------- /archive/06.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Debugging Gstreamer " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "#https://github.com/nnstreamer/nnstreamer/blob/main/tools/debugging/README.md" 17 | ] 18 | } 19 | ], 20 | "metadata": { 21 | "language_info": { 22 | "name": "python" 23 | }, 24 | "orig_nbformat": 4 25 | }, 26 | "nbformat": 4, 27 | "nbformat_minor": 2 28 | } 29 | -------------------------------------------------------------------------------- /archive/07.ipynb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/07.ipynb -------------------------------------------------------------------------------- /archive/08.ipynb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/08.ipynb -------------------------------------------------------------------------------- /archive/README.md: -------------------------------------------------------------------------------- 1 | # Edge Computing Workshop 2 | 3 | - Slides Link 4 | - Document Link 5 | 6 | ## Install system dependencies: 7 | ``` 8 | chmod a+x system_setup.sh 9 | ``` 10 | Run the command below: 11 | ``` 12 | ./system_setup.sh 13 | ``` 14 | 15 | 16 | ## Setup Docker image and start Docker container: 17 | ``` 18 | chmod a+x docker_run.sh 19 | ``` 20 | Please ensure the webcam is connected to the Nano. Then run the command below: 21 | ``` 22 | ./docker_run.sh 23 | ``` 24 | 25 | ## Start Jupyter notebook 26 | ``` 27 | ai6@ai6-desktop:~/Documents/ai6/edge-computing/my_apps$ ./docker_run.sh 28 | allow 10 sec for JupyterLab to start @ http://192.*.*.**:8888 (password dlinano) 29 | JupterLab logging location: /var/log/jupyter.log (inside the container) 30 | root@ai6-desktop:/dli/task# 31 | 32 | ``` 33 | Click on the url http://192.*.*.**:8888 to access the Jupyter Lab and enter the password:dlinano 34 | 35 | 36 | ## Table of Contents 37 | - 1 Object Detection Application 38 | - 2 Analysis with Metadata 39 | - 3 Multiple Networks Application 40 | - 4 Multiple Stream Input 41 | - 5 Video File Output 42 | - 6 Different Neural Networks 43 | - 7 Live Stream -------------------------------------------------------------------------------- /archive/docker_run.sh: -------------------------------------------------------------------------------- 1 | export DISPLAY=:0 2 | sudo docker run --runtime nvidia -it --rm --network host \ 3 | -v /tmp/.X11-unix/:/tmp/.X11-unix \ 4 | -v /tmp/argus_socket:/tmp/argus_socket \ 5 | -v ~/my_apps:/dli/task/my_apps \ 6 | --device /dev/video0 \ 7 | nvcr.io/nvidia/dli/dli-nano-deepstream:v2.0.0-DS6.0.1 8 | 9 | -------------------------------------------------------------------------------- /archive/sample_stream/sample_1080p_h264.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/sample_stream/sample_1080p_h264.mp4 -------------------------------------------------------------------------------- /archive/sample_stream/sample_1080p_h265.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/sample_stream/sample_1080p_h265.mp4 -------------------------------------------------------------------------------- /archive/sample_stream/sample_720p.h264: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/sample_stream/sample_720p.h264 -------------------------------------------------------------------------------- /archive/system_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # First update the newly flashed os 3 | sudo apt-get update 4 | # Install systems dependencies 5 | # Download Docker 6 | wget https://launchpadlibrarian.net/511874292/docker.io_19.03.6-0ubuntu1~18.04.3_arm64.deb 7 | # Install Docker 8 | sudo dpkg -i docker.io_19.03.6-0ubuntu1~18.04.3_arm64.deb 9 | # Remove Docker .deb 10 | rm -rf docker.io_19.03.6-0ubuntu1~18.04.3_arm64.deb 11 | # Install pip(s) 12 | sudo apt-get install -y python3-pip 13 | sudo apt-get install -y python-pip 14 | # Install JTop 15 | sudo -H pip install -U jetson-stats 16 | # Install Docker compose 17 | sudo apt-get install curl libffi-dev python-openssl libssl-dev zlib1g-dev gcc g++ make -y 18 | sudo pip3 install docker-compose 19 | sudo docker-compose --version 20 | # Reboot to enable jTop 21 | sudo reboot 22 | # Enable swapfile with jTop 23 | # Update the jetson again -------------------------------------------------------------------------------- /archive/test1/README: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | Prequisites: 19 | - DeepStreamSDK 6.0.1 20 | - Python 3.6 21 | - Gst-python 22 | 23 | To run the test app: 24 | $ python3 deepstream_test_1.py 25 | 26 | This document shall describe the sample deepstream-test1 application. 27 | 28 | It is meant for simple demonstration of how to use the various DeepStream SDK 29 | elements in the pipeline and extract meaningful insights from a video stream. 30 | 31 | This sample creates instance of "nvinfer" element. Instance of 32 | the "nvinfer" uses TensorRT API to execute inferencing on a model. Using a 33 | correct configuration for a nvinfer element instance is therefore very 34 | important as considerable behaviors of the instance are parameterized 35 | through these configs. 36 | 37 | For reference, here are the config files used for this sample : 38 | 1. The 4-class detector (referred to as pgie in this sample) uses 39 | dstest1_pgie_config.txt 40 | 41 | In this sample, we first create one instance of "nvinfer", referred as the pgie. 42 | This is our 4 class detector and it detects for "Vehicle , RoadSign, TwoWheeler, 43 | Person". 44 | nvinfer element attach some MetaData to the buffer. By attaching 45 | the probe function at the end of the pipeline, one can extract meaningful 46 | information from this inference. Please refer the "osd_sink_pad_buffer_probe" 47 | function in the sample code. For details on the Metadata format, refer to the 48 | file "gstnvdsmeta.h" 49 | 50 | -------------------------------------------------------------------------------- /archive/test1/common/FPS.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a 5 | # copy of this software and associated documentation files (the "Software"), 6 | # to deal in the Software without restriction, including without limitation 7 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | # and/or sell copies of the Software, and to permit persons to whom the 9 | # Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | # DEALINGS IN THE SOFTWARE. 21 | ################################################################################ 22 | 23 | import time 24 | start_time=time.time() 25 | frame_count=0 26 | 27 | class GETFPS: 28 | def __init__(self,stream_id): 29 | global start_time 30 | self.start_time=start_time 31 | self.is_first=True 32 | global frame_count 33 | self.frame_count=frame_count 34 | self.stream_id=stream_id 35 | def get_fps(self): 36 | end_time=time.time() 37 | if(self.is_first): 38 | self.start_time=end_time 39 | self.is_first=False 40 | if(end_time-self.start_time>5): 41 | print("**********************FPS*****************************************") 42 | print("Fps of stream",self.stream_id,"is ", float(self.frame_count)/5.0) 43 | self.frame_count=0 44 | self.start_time=end_time 45 | else: 46 | self.frame_count=self.frame_count+1 47 | def print_data(self): 48 | print('frame_count=',self.frame_count) 49 | print('start_time=',self.start_time) 50 | 51 | -------------------------------------------------------------------------------- /archive/test1/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/test1/common/__init__.py -------------------------------------------------------------------------------- /archive/test1/common/__pycache__/FPS.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/test1/common/__pycache__/FPS.cpython-36.pyc -------------------------------------------------------------------------------- /archive/test1/common/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/test1/common/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /archive/test1/common/__pycache__/bus_call.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/test1/common/__pycache__/bus_call.cpython-36.pyc -------------------------------------------------------------------------------- /archive/test1/common/__pycache__/is_aarch_64.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/archive/test1/common/__pycache__/is_aarch_64.cpython-36.pyc -------------------------------------------------------------------------------- /archive/test1/common/bus_call.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a 5 | # copy of this software and associated documentation files (the "Software"), 6 | # to deal in the Software without restriction, including without limitation 7 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | # and/or sell copies of the Software, and to permit persons to whom the 9 | # Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | # DEALINGS IN THE SOFTWARE. 21 | ################################################################################ 22 | 23 | import gi 24 | import sys 25 | gi.require_version('Gst', '1.0') 26 | from gi.repository import GObject, Gst 27 | def bus_call(bus, message, loop): 28 | t = message.type 29 | if t == Gst.MessageType.EOS: 30 | sys.stdout.write("End-of-stream\n") 31 | loop.quit() 32 | elif t==Gst.MessageType.WARNING: 33 | err, debug = message.parse_warning() 34 | sys.stderr.write("Warning: %s: %s\n" % (err, debug)) 35 | elif t == Gst.MessageType.ERROR: 36 | err, debug = message.parse_error() 37 | sys.stderr.write("Error: %s: %s\n" % (err, debug)) 38 | loop.quit() 39 | return True 40 | -------------------------------------------------------------------------------- /archive/test1/common/is_aarch_64.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a 5 | # copy of this software and associated documentation files (the "Software"), 6 | # to deal in the Software without restriction, including without limitation 7 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | # and/or sell copies of the Software, and to permit persons to whom the 9 | # Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | # DEALINGS IN THE SOFTWARE. 21 | ################################################################################ 22 | 23 | import platform 24 | import sys 25 | 26 | 27 | def is_aarch64(): 28 | return platform.uname()[4] == 'aarch64' 29 | 30 | sys.path.append('/opt/nvidia/deepstream/deepstream/lib') 31 | -------------------------------------------------------------------------------- /archive/test1/common/utils.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a 5 | # copy of this software and associated documentation files (the "Software"), 6 | # to deal in the Software without restriction, including without limitation 7 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | # and/or sell copies of the Software, and to permit persons to whom the 9 | # Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | # DEALINGS IN THE SOFTWARE. 21 | ################################################################################ 22 | 23 | import ctypes 24 | import sys 25 | sys.path.append('/opt/nvidia/deepstream/deepstream/lib') 26 | 27 | def long_to_int(l): 28 | value = ctypes.c_int(l & 0xffffffff).value 29 | return value 30 | -------------------------------------------------------------------------------- /archive/test1/deepstream_test_1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ################################################################################ 4 | # SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | ################################################################################ 19 | 20 | import sys 21 | #sys.path.append('../../') 22 | sys.path.append('/opt/nvidia/deepstream/deepstream-5.1/sources/deepstream_python_apps/apps/common') 23 | sys.path.append('/dli/task/my_apps/') 24 | import gi 25 | gi.require_version('Gst', '1.0') 26 | from gi.repository import GObject, Gst 27 | from common.is_aarch_64 import is_aarch64 28 | from common.bus_call import bus_call 29 | 30 | import pyds 31 | 32 | PGIE_CLASS_ID_VEHICLE = 0 33 | PGIE_CLASS_ID_BICYCLE = 1 34 | PGIE_CLASS_ID_PERSON = 2 35 | PGIE_CLASS_ID_ROADSIGN = 3 36 | 37 | 38 | def osd_sink_pad_buffer_probe(pad,info,u_data): 39 | frame_number=0 40 | #Intiallizing object counter with 0. 41 | obj_counter = { 42 | PGIE_CLASS_ID_VEHICLE:0, 43 | PGIE_CLASS_ID_PERSON:0, 44 | PGIE_CLASS_ID_BICYCLE:0, 45 | PGIE_CLASS_ID_ROADSIGN:0 46 | } 47 | num_rects=0 48 | 49 | gst_buffer = info.get_buffer() 50 | if not gst_buffer: 51 | print("Unable to get GstBuffer ") 52 | return 53 | 54 | # Retrieve batch metadata from the gst_buffer 55 | # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the 56 | # C address of gst_buffer as input, which is obtained with hash(gst_buffer) 57 | batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) 58 | l_frame = batch_meta.frame_meta_list 59 | while l_frame is not None: 60 | try: 61 | # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta 62 | # The casting is done by pyds.glist_get_nvds_frame_meta() 63 | # The casting also keeps ownership of the underlying memory 64 | # in the C code, so the Python garbage collector will leave 65 | # it alone. 66 | #frame_meta = pyds.glist_get_nvds_frame_meta(l_frame.data) 67 | frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data) 68 | except StopIteration: 69 | break 70 | 71 | frame_number=frame_meta.frame_num 72 | num_rects = frame_meta.num_obj_meta 73 | l_obj=frame_meta.obj_meta_list 74 | while l_obj is not None: 75 | try: 76 | # Casting l_obj.data to pyds.NvDsObjectMeta 77 | #obj_meta=pyds.glist_get_nvds_object_meta(l_obj.data) 78 | obj_meta=pyds.NvDsObjectMeta.cast(l_obj.data) 79 | except StopIteration: 80 | break 81 | obj_counter[obj_meta.class_id] += 1 82 | obj_meta.rect_params.border_color.set(0.0, 0.0, 1.0, 0.0) 83 | try: 84 | l_obj=l_obj.next 85 | except StopIteration: 86 | break 87 | 88 | # Acquiring a display meta object. The memory ownership remains in 89 | # the C code so downstream plugins can still access it. Otherwise 90 | # the garbage collector will claim it when this probe function exits. 91 | display_meta=pyds.nvds_acquire_display_meta_from_pool(batch_meta) 92 | display_meta.num_labels = 1 93 | py_nvosd_text_params = display_meta.text_params[0] 94 | # Setting display text to be shown on screen 95 | # Note that the pyds module allocates a buffer for the string, and the 96 | # memory will not be claimed by the garbage collector. 97 | # Reading the display_text field here will return the C address of the 98 | # allocated string. Use pyds.get_string() to get the string content. 99 | py_nvosd_text_params.display_text = "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]) 100 | 101 | # Now set the offsets where the string should appear 102 | py_nvosd_text_params.x_offset = 10 103 | py_nvosd_text_params.y_offset = 12 104 | 105 | # Font , font-color and font-size 106 | py_nvosd_text_params.font_params.font_name = "Serif" 107 | py_nvosd_text_params.font_params.font_size = 10 108 | # set(red, green, blue, alpha); set to White 109 | py_nvosd_text_params.font_params.font_color.set(1.0, 1.0, 1.0, 1.0) 110 | 111 | # Text background color 112 | py_nvosd_text_params.set_bg_clr = 1 113 | # set(red, green, blue, alpha); set to Black 114 | py_nvosd_text_params.text_bg_clr.set(0.0, 0.0, 0.0, 1.0) 115 | # Using pyds.get_string() to get display_text as string 116 | print(pyds.get_string(py_nvosd_text_params.display_text)) 117 | pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta) 118 | try: 119 | l_frame=l_frame.next 120 | except StopIteration: 121 | break 122 | 123 | return Gst.PadProbeReturn.OK 124 | 125 | 126 | def main(args): 127 | # Check input arguments 128 | if len(args) != 2: 129 | sys.stderr.write("usage: %s \n" % args[0]) 130 | sys.exit(1) 131 | 132 | # Standard GStreamer initialization 133 | GObject.threads_init() 134 | Gst.init(None) 135 | 136 | # Create gstreamer elements 137 | # Create Pipeline element that will form a connection of other elements 138 | print("Creating Pipeline \n ") 139 | pipeline = Gst.Pipeline() 140 | 141 | if not pipeline: 142 | sys.stderr.write(" Unable to create Pipeline \n") 143 | 144 | # Source element for reading from the file 145 | print("Creating Source \n ") 146 | source = Gst.ElementFactory.make("filesrc", "file-source") 147 | if not source: 148 | sys.stderr.write(" Unable to create Source \n") 149 | 150 | # Since the data format in the input file is elementary h264 stream, 151 | # we need a h264parser 152 | print("Creating H264Parser \n") 153 | h264parser = Gst.ElementFactory.make("h264parse", "h264-parser") 154 | if not h264parser: 155 | sys.stderr.write(" Unable to create h264 parser \n") 156 | 157 | # Use nvdec_h264 for hardware accelerated decode on GPU 158 | print("Creating Decoder \n") 159 | decoder = Gst.ElementFactory.make("nvv4l2decoder", "nvv4l2-decoder") 160 | if not decoder: 161 | sys.stderr.write(" Unable to create Nvv4l2 Decoder \n") 162 | 163 | # Create nvstreammux instance to form batches from one or more sources. 164 | streammux = Gst.ElementFactory.make("nvstreammux", "Stream-muxer") 165 | if not streammux: 166 | sys.stderr.write(" Unable to create NvStreamMux \n") 167 | 168 | # Use nvinfer to run inferencing on decoder's output, 169 | # behaviour of inferencing is set through config file 170 | pgie = Gst.ElementFactory.make("nvinfer", "primary-inference") 171 | if not pgie: 172 | sys.stderr.write(" Unable to create pgie \n") 173 | 174 | # Use convertor to convert from NV12 to RGBA as required by nvosd 175 | nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor") 176 | if not nvvidconv: 177 | sys.stderr.write(" Unable to create nvvidconv \n") 178 | 179 | # Create OSD to draw on the converted RGBA buffer 180 | nvosd = Gst.ElementFactory.make("nvdsosd", "onscreendisplay") 181 | 182 | if not nvosd: 183 | sys.stderr.write(" Unable to create nvosd \n") 184 | 185 | # Finally render the osd output 186 | if is_aarch64(): 187 | transform = Gst.ElementFactory.make("nvegltransform", "nvegl-transform") 188 | 189 | print("Creating EGLSink \n") 190 | sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer") 191 | if not sink: 192 | sys.stderr.write(" Unable to create egl sink \n") 193 | 194 | print("Playing file %s " %args[1]) 195 | source.set_property('location', args[1]) 196 | streammux.set_property('width', 1920) 197 | streammux.set_property('height', 1080) 198 | streammux.set_property('batch-size', 1) 199 | streammux.set_property('batched-push-timeout', 4000000) 200 | pgie.set_property('config-file-path', "dstest1_pgie_config.txt") 201 | 202 | print("Adding elements to Pipeline \n") 203 | pipeline.add(source) 204 | pipeline.add(h264parser) 205 | pipeline.add(decoder) 206 | pipeline.add(streammux) 207 | pipeline.add(pgie) 208 | pipeline.add(nvvidconv) 209 | pipeline.add(nvosd) 210 | pipeline.add(sink) 211 | if is_aarch64(): 212 | pipeline.add(transform) 213 | 214 | # we link the elements together 215 | # file-source -> h264-parser -> nvh264-decoder -> 216 | # nvinfer -> nvvidconv -> nvosd -> video-renderer 217 | print("Linking elements in the Pipeline \n") 218 | source.link(h264parser) 219 | h264parser.link(decoder) 220 | 221 | sinkpad = streammux.get_request_pad("sink_0") 222 | if not sinkpad: 223 | sys.stderr.write(" Unable to get the sink pad of streammux \n") 224 | srcpad = decoder.get_static_pad("src") 225 | if not srcpad: 226 | sys.stderr.write(" Unable to get source pad of decoder \n") 227 | srcpad.link(sinkpad) 228 | streammux.link(pgie) 229 | pgie.link(nvvidconv) 230 | nvvidconv.link(nvosd) 231 | if is_aarch64(): 232 | nvosd.link(transform) 233 | transform.link(sink) 234 | else: 235 | nvosd.link(sink) 236 | 237 | # create an event loop and feed gstreamer bus mesages to it 238 | loop = GObject.MainLoop() 239 | bus = pipeline.get_bus() 240 | bus.add_signal_watch() 241 | bus.connect ("message", bus_call, loop) 242 | 243 | # Lets add probe to get informed of the meta data generated, we add probe to 244 | # the sink pad of the osd element, since by that time, the buffer would have 245 | # had got all the metadata. 246 | osdsinkpad = nvosd.get_static_pad("sink") 247 | if not osdsinkpad: 248 | sys.stderr.write(" Unable to get sink pad of nvosd \n") 249 | 250 | osdsinkpad.add_probe(Gst.PadProbeType.BUFFER, osd_sink_pad_buffer_probe, 0) 251 | 252 | # start play back and listen to events 253 | print("Starting pipeline \n") 254 | pipeline.set_state(Gst.State.PLAYING) 255 | try: 256 | loop.run() 257 | except: 258 | pass 259 | # cleanup 260 | pipeline.set_state(Gst.State.NULL) 261 | 262 | if __name__ == '__main__': 263 | sys.exit(main(sys.argv)) 264 | 265 | -------------------------------------------------------------------------------- /archive/test1/dstest1_pgie_config.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ################################################################################ 17 | 18 | # Following properties are mandatory when engine files are not specified: 19 | # int8-calib-file(Only in INT8) 20 | # Caffemodel mandatory properties: model-file, proto-file, output-blob-names 21 | # UFF: uff-file, input-dims, uff-input-blob-name, output-blob-names 22 | # ONNX: onnx-file 23 | # 24 | # Mandatory properties for detectors: 25 | # num-detected-classes 26 | # 27 | # Optional properties for detectors: 28 | # cluster-mode(Default=Group Rectangles), interval(Primary mode only, Default=0) 29 | # custom-lib-path, 30 | # parse-bbox-func-name 31 | # 32 | # Mandatory properties for classifiers: 33 | # classifier-threshold, is-classifier 34 | # 35 | # Optional properties for classifiers: 36 | # classifier-async-mode(Secondary mode only, Default=false) 37 | # 38 | # Optional properties in secondary mode: 39 | # operate-on-gie-id(Default=0), operate-on-class-ids(Defaults to all classes), 40 | # input-object-min-width, input-object-min-height, input-object-max-width, 41 | # input-object-max-height 42 | # 43 | # Following properties are always recommended: 44 | # batch-size(Default=1) 45 | # 46 | # Other optional properties: 47 | # net-scale-factor(Default=1), network-mode(Default=0 i.e FP32), 48 | # model-color-format(Default=0 i.e. RGB) model-engine-file, labelfile-path, 49 | # mean-file, gie-unique-id(Default=0), offsets, process-mode (Default=1 i.e. primary), 50 | # custom-lib-path, network-mode(Default=0 i.e FP32) 51 | # 52 | # The values in the config file are overridden by values set through GObject 53 | # properties. 54 | 55 | [property] 56 | gpu-id=0 57 | net-scale-factor=0.0039215697906911373 58 | #model-file=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/resnet10.caffemodel 59 | model-file=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/resnet10.caffemodel 60 | proto-file=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/resnet10.prototxt 61 | model-engine-file=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_fp16.engine 62 | labelfile-path=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/labels.txt 63 | int8-calib-file=/opt/nvidia/deepstream/deepstream-5.1/samples/models/Primary_Detector/cal_trt.bin 64 | force-implicit-batch-dim=1 65 | batch-size=1 66 | network-mode=1 67 | num-detected-classes=4 68 | interval=0 69 | gie-unique-id=1 70 | output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid 71 | #scaling-filter=0 72 | #scaling-compute-hw=0 73 | 74 | [class-attrs-all] 75 | pre-cluster-threshold=0.2 76 | eps=0.2 77 | group-threshold=1 78 | -------------------------------------------------------------------------------- /archive/test1/pipeline1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | 4 | import gi 5 | 6 | gi.require_version('GLib', '2.0') 7 | gi.require_version('GObject', '2.0') 8 | gi.require_version('Gst', '1.0') 9 | 10 | from gi.repository import Gst, GObject, GLib 11 | 12 | pipeline = None 13 | bus = None 14 | message = None 15 | 16 | # initialize GStreamer 17 | Gst.init(sys.argv[1:]) 18 | 19 | # build the pipeline 20 | pipeline = Gst.parse_launch( 21 | "playbin uri=file:///home/hlk/Documents/ai6/edge-computing/my_apps/sample_stream/sample_1080p_h265.mp4" 22 | ) 23 | 24 | # start playing 25 | pipeline.set_state(Gst.State.PLAYING) 26 | 27 | # wait until EOS or error 28 | bus = pipeline.get_bus() 29 | msg = bus.timed_pop_filtered( 30 | Gst.CLOCK_TIME_NONE, 31 | Gst.MessageType.ERROR | Gst.MessageType.EOS 32 | ) 33 | 34 | # free resources 35 | pipeline.set_state(Gst.State.NULL) 36 | 37 | 38 | # /dli/task/deepstream/samples/streams/yoga.mp4 39 | # https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm -------------------------------------------------------------------------------- /archive/test1/pipeline2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+2%3A+GStreamer+concepts 4 | 5 | import sys 6 | import gi 7 | gi.require_version('Gst', '1.0') 8 | from gi.repository import Gst, GLib, GObject 9 | 10 | # initialize GStreamer 11 | Gst.init(None) 12 | 13 | print(sys.argv[1]) 14 | 15 | # create the elements 16 | # source = Gst.ElementFactory.make("filesrc", "file-source") 17 | source = Gst.ElementFactory.make("videotestsrc", "source") 18 | sink = Gst.ElementFactory.make("autovideosink", "sink") 19 | # sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer") 20 | 21 | # create the empty pipeline 22 | pipeline = Gst.Pipeline.new("test-pipeline") 23 | 24 | if not pipeline or not source or not sink: 25 | print("ERROR: Not all elements could be created") 26 | sys.exit(1) 27 | 28 | # build the pipeline 29 | pipeline.add(source, sink) 30 | if not source.link(sink): 31 | print("ERROR: Could not link source to sink") 32 | sys.exit(1) 33 | 34 | # modify the source's properties 35 | # source.set_property('location', sys.argv[1]) 36 | source.set_property("pattern", 0) 37 | 38 | # start playing 39 | ret = pipeline.set_state(Gst.State.PLAYING) 40 | if ret == Gst.StateChangeReturn.FAILURE: 41 | print("ERROR: Unable to set the pipeline to the playing state") 42 | 43 | # wait for EOS or error 44 | bus = pipeline.get_bus() 45 | msg = bus.timed_pop_filtered( 46 | Gst.CLOCK_TIME_NONE, 47 | Gst.MessageType.ERROR | Gst.MessageType.EOS 48 | ) 49 | 50 | if msg: 51 | t = msg.type 52 | if t == Gst.MessageType.ERROR: 53 | err, dbg = msg.parse_error() 54 | print("ERROR:", msg.src.get_name(), " ", err.message) 55 | if dbg: 56 | print("debugging info:", dbg) 57 | elif t == Gst.MessageType.EOS: 58 | print("End-Of-Stream reached") 59 | else: 60 | # this should not happen. we only asked for ERROR and EOS 61 | print("ERROR: Unexpected message received.") 62 | 63 | pipeline.set_state(Gst.State.NULL) -------------------------------------------------------------------------------- /archive/test1/pipeline2b.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+2%3A+GStreamer+concepts 4 | 5 | import sys 6 | import gi 7 | gi.require_version('Gst', '1.0') 8 | from gi.repository import Gst, GLib, GObject 9 | 10 | # initialize GStreamer 11 | Gst.init(None) 12 | 13 | def main(args): 14 | # Check input arguments 15 | if len(args) != 2: 16 | sys.stderr.write("usage: %s \n" % args[0]) 17 | sys.exit(1) 18 | 19 | # create the elements 20 | source = Gst.ElementFactory.make("filesrc", "file-source") 21 | # source = Gst.ElementFactory.make("videotestsrc", "source") 22 | sink = Gst.ElementFactory.make("autovideosink", "sink") 23 | 24 | # create the empty pipeline 25 | pipeline = Gst.Pipeline.new("test-pipeline") 26 | 27 | if not pipeline or not source or not sink: 28 | print("ERROR: Not all elements could be created") 29 | sys.exit(1) 30 | 31 | # build the pipeline 32 | pipeline.add(source, sink) 33 | if not source.link(sink): 34 | print("ERROR: Could not link source to sink") 35 | sys.exit(1) 36 | 37 | # modify the source's properties 38 | source.set_property('location', sys.argv[1]) 39 | #source.set_property("pattern", 0) 40 | 41 | # start playing 42 | ret = pipeline.set_state(Gst.State.PLAYING) 43 | if ret == Gst.StateChangeReturn.FAILURE: 44 | print("ERROR: Unable to set the pipeline to the playing state") 45 | 46 | # wait for EOS or error 47 | bus = pipeline.get_bus() 48 | msg = bus.timed_pop_filtered( 49 | Gst.CLOCK_TIME_NONE, 50 | Gst.MessageType.ERROR | Gst.MessageType.EOS 51 | ) 52 | 53 | if msg: 54 | t = msg.type 55 | if t == Gst.MessageType.ERROR: 56 | err, dbg = msg.parse_error() 57 | print("ERROR:", msg.src.get_name(), " ", err.message) 58 | if dbg: 59 | print("debugging info:", dbg) 60 | elif t == Gst.MessageType.EOS: 61 | print("End-Of-Stream reached") 62 | else: 63 | # this should not happen. we only asked for ERROR and EOS 64 | print("ERROR: Unexpected message received.") 65 | 66 | pipeline.set_state(Gst.State.NULL) 67 | 68 | if __name__ == "__main__": 69 | sys.exit(main(sys.argv)) -------------------------------------------------------------------------------- /archive/test1/pipeline3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ################################################################################ 4 | # SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | ################################################################################ 19 | 20 | import sys 21 | #sys.path.append('../../') 22 | sys.path.append('/dli/task/my_apps/') 23 | import gi 24 | gi.require_version('Gst', '1.0') 25 | from gi.repository import GObject, Gst 26 | from common.is_aarch_64 import is_aarch64 27 | from common.bus_call import bus_call 28 | 29 | import pyds 30 | 31 | PGIE_CLASS_ID_VEHICLE = 0 32 | PGIE_CLASS_ID_BICYCLE = 1 33 | PGIE_CLASS_ID_PERSON = 2 34 | PGIE_CLASS_ID_ROADSIGN = 3 35 | 36 | 37 | def osd_sink_pad_buffer_probe(pad,info,u_data): 38 | frame_number=0 39 | #Intiallizing object counter with 0. 40 | obj_counter = { 41 | PGIE_CLASS_ID_VEHICLE:0, 42 | PGIE_CLASS_ID_PERSON:0, 43 | PGIE_CLASS_ID_BICYCLE:0, 44 | PGIE_CLASS_ID_ROADSIGN:0 45 | } 46 | num_rects=0 47 | 48 | gst_buffer = info.get_buffer() 49 | if not gst_buffer: 50 | print("Unable to get GstBuffer ") 51 | return 52 | 53 | # Retrieve batch metadata from the gst_buffer 54 | # Note that pyds.gst_buffer_get_nvds_batch_meta() expects the 55 | # C address of gst_buffer as input, which is obtained with hash(gst_buffer) 56 | batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer)) 57 | l_frame = batch_meta.frame_meta_list 58 | while l_frame is not None: 59 | try: 60 | # Note that l_frame.data needs a cast to pyds.NvDsFrameMeta 61 | # The casting is done by pyds.glist_get_nvds_frame_meta() 62 | # The casting also keeps ownership of the underlying memory 63 | # in the C code, so the Python garbage collector will leave 64 | # it alone. 65 | #frame_meta = pyds.glist_get_nvds_frame_meta(l_frame.data) 66 | frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data) 67 | except StopIteration: 68 | break 69 | 70 | frame_number=frame_meta.frame_num 71 | num_rects = frame_meta.num_obj_meta 72 | l_obj=frame_meta.obj_meta_list 73 | while l_obj is not None: 74 | try: 75 | # Casting l_obj.data to pyds.NvDsObjectMeta 76 | #obj_meta=pyds.glist_get_nvds_object_meta(l_obj.data) 77 | obj_meta=pyds.NvDsObjectMeta.cast(l_obj.data) 78 | except StopIteration: 79 | break 80 | obj_counter[obj_meta.class_id] += 1 81 | obj_meta.rect_params.border_color.set(0.0, 0.0, 1.0, 0.0) 82 | try: 83 | l_obj=l_obj.next 84 | except StopIteration: 85 | break 86 | 87 | # Acquiring a display meta object. The memory ownership remains in 88 | # the C code so downstream plugins can still access it. Otherwise 89 | # the garbage collector will claim it when this probe function exits. 90 | display_meta=pyds.nvds_acquire_display_meta_from_pool(batch_meta) 91 | display_meta.num_labels = 1 92 | py_nvosd_text_params = display_meta.text_params[0] 93 | # Setting display text to be shown on screen 94 | # Note that the pyds module allocates a buffer for the string, and the 95 | # memory will not be claimed by the garbage collector. 96 | # Reading the display_text field here will return the C address of the 97 | # allocated string. Use pyds.get_string() to get the string content. 98 | py_nvosd_text_params.display_text = "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]) 99 | 100 | # Now set the offsets where the string should appear 101 | py_nvosd_text_params.x_offset = 10 102 | py_nvosd_text_params.y_offset = 12 103 | 104 | # Font , font-color and font-size 105 | py_nvosd_text_params.font_params.font_name = "Serif" 106 | py_nvosd_text_params.font_params.font_size = 10 107 | # set(red, green, blue, alpha); set to White 108 | py_nvosd_text_params.font_params.font_color.set(1.0, 1.0, 1.0, 1.0) 109 | 110 | # Text background color 111 | py_nvosd_text_params.set_bg_clr = 1 112 | # set(red, green, blue, alpha); set to Black 113 | py_nvosd_text_params.text_bg_clr.set(0.0, 0.0, 0.0, 1.0) 114 | # Using pyds.get_string() to get display_text as string 115 | print(pyds.get_string(py_nvosd_text_params.display_text)) 116 | pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta) 117 | try: 118 | l_frame=l_frame.next 119 | except StopIteration: 120 | break 121 | 122 | return Gst.PadProbeReturn.OK 123 | 124 | 125 | def main(args): 126 | # Check input arguments 127 | if len(args) != 2: 128 | sys.stderr.write("usage: %s \n" % args[0]) 129 | sys.exit(1) 130 | 131 | # Standard GStreamer initialization 132 | GObject.threads_init() 133 | Gst.init(None) 134 | 135 | # Create gstreamer elements 136 | # Create Pipeline element that will form a connection of other elements 137 | print("Creating Pipeline \n ") 138 | pipeline = Gst.Pipeline() 139 | 140 | if not pipeline: 141 | sys.stderr.write(" Unable to create Pipeline \n") 142 | 143 | # Source element for reading from the file 144 | print("Creating Source \n ") 145 | source = Gst.ElementFactory.make("filesrc", "file-source") 146 | if not source: 147 | sys.stderr.write(" Unable to create Source \n") 148 | 149 | # Since the data format in the input file is elementary h264 stream, 150 | # we need a h264parser 151 | print("Creating H264Parser \n") 152 | h264parser = Gst.ElementFactory.make("h264parse", "h264-parser") 153 | if not h264parser: 154 | sys.stderr.write(" Unable to create h264 parser \n") 155 | 156 | # Use nvdec_h264 for hardware accelerated decode on GPU 157 | print("Creating Decoder \n") 158 | decoder = Gst.ElementFactory.make("nvv4l2decoder", "nvv4l2-decoder") 159 | if not decoder: 160 | sys.stderr.write(" Unable to create Nvv4l2 Decoder \n") 161 | 162 | # Create nvstreammux instance to form batches from one or more sources. 163 | streammux = Gst.ElementFactory.make("nvstreammux", "Stream-muxer") 164 | if not streammux: 165 | sys.stderr.write(" Unable to create NvStreamMux \n") 166 | 167 | # Use nvinfer to run inferencing on decoder's output, 168 | # behaviour of inferencing is set through config file 169 | pgie = Gst.ElementFactory.make("nvinfer", "primary-inference") 170 | if not pgie: 171 | sys.stderr.write(" Unable to create pgie \n") 172 | 173 | # Use convertor to convert from NV12 to RGBA as required by nvosd 174 | nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor") 175 | if not nvvidconv: 176 | sys.stderr.write(" Unable to create nvvidconv \n") 177 | 178 | # Create OSD to draw on the converted RGBA buffer 179 | nvosd = Gst.ElementFactory.make("nvdsosd", "onscreendisplay") 180 | 181 | if not nvosd: 182 | sys.stderr.write(" Unable to create nvosd \n") 183 | 184 | # Finally render the osd output 185 | if is_aarch64(): 186 | transform = Gst.ElementFactory.make("nvegltransform", "nvegl-transform") 187 | 188 | print("Creating EGLSink \n") 189 | sink = Gst.ElementFactory.make("nveglglessink", "nvvideo-renderer") 190 | if not sink: 191 | sys.stderr.write(" Unable to create egl sink \n") 192 | 193 | print("Playing file %s " %args[1]) 194 | source.set_property('location', args[1]) 195 | streammux.set_property('width', 1920) 196 | streammux.set_property('height', 1080) 197 | streammux.set_property('batch-size', 1) 198 | streammux.set_property('batched-push-timeout', 4000000) 199 | pgie.set_property('config-file-path', "dstest1_pgie_config.txt") 200 | 201 | print("Adding elements to Pipeline \n") 202 | pipeline.add(source) 203 | pipeline.add(h264parser) 204 | pipeline.add(decoder) 205 | pipeline.add(streammux) 206 | pipeline.add(pgie) 207 | pipeline.add(nvvidconv) 208 | pipeline.add(nvosd) 209 | pipeline.add(sink) 210 | if is_aarch64(): 211 | pipeline.add(transform) 212 | 213 | # we link the elements together 214 | # file-source -> h264-parser -> nvh264-decoder -> 215 | # nvinfer -> nvvidconv -> nvosd -> video-renderer 216 | print("Linking elements in the Pipeline \n") 217 | source.link(h264parser) 218 | h264parser.link(decoder) 219 | 220 | sinkpad = streammux.get_request_pad("sink_0") 221 | if not sinkpad: 222 | sys.stderr.write(" Unable to get the sink pad of streammux \n") 223 | srcpad = decoder.get_static_pad("src") 224 | if not srcpad: 225 | sys.stderr.write(" Unable to get source pad of decoder \n") 226 | srcpad.link(sinkpad) 227 | streammux.link(pgie) 228 | pgie.link(nvvidconv) 229 | nvvidconv.link(nvosd) 230 | if is_aarch64(): 231 | nvosd.link(transform) 232 | transform.link(sink) 233 | else: 234 | nvosd.link(sink) 235 | 236 | # create an event loop and feed gstreamer bus mesages to it 237 | loop = GObject.MainLoop() 238 | bus = pipeline.get_bus() 239 | bus.add_signal_watch() 240 | bus.connect ("message", bus_call, loop) 241 | 242 | # Lets add probe to get informed of the meta data generated, we add probe to 243 | # the sink pad of the osd element, since by that time, the buffer would have 244 | # had got all the metadata. 245 | # osdsinkpad = nvosd.get_static_pad("sink") 246 | # if not osdsinkpad: 247 | # sys.stderr.write(" Unable to get sink pad of nvosd \n") 248 | 249 | # osdsinkpad.add_probe(Gst.PadProbeType.BUFFER, osd_sink_pad_buffer_probe, 0) 250 | 251 | # start play back and listen to events 252 | print("Starting pipeline \n") 253 | pipeline.set_state(Gst.State.PLAYING) 254 | try: 255 | loop.run() 256 | except: 257 | pass 258 | # cleanup 259 | pipeline.set_state(Gst.State.NULL) 260 | 261 | if __name__ == '__main__': 262 | sys.exit(main(sys.argv)) 263 | 264 | -------------------------------------------------------------------------------- /archive/test1/pipeline4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+2%3A+GStreamer+concepts 4 | 5 | import sys 6 | import gi 7 | gi.require_version('Gst', '1.0') 8 | from gi.repository import Gst, GLib, GObject 9 | 10 | # initialize GStreamer 11 | Gst.init(None) 12 | 13 | # create the elements 14 | source = Gst.ElementFactory.make("videotestsrc", "source") 15 | sink = Gst.ElementFactory.make("autovideosink", "sink") 16 | 17 | # create the empty pipeline 18 | pipeline = Gst.Pipeline.new("test-pipeline") 19 | 20 | if not pipeline or not source or not sink: 21 | print("ERROR: Not all elements could be created") 22 | sys.exit(1) 23 | 24 | # build the pipeline 25 | pipeline.add(source, sink) 26 | if not source.link(sink): 27 | print("ERROR: Could not link source to sink") 28 | sys.exit(1) 29 | 30 | # modify the source's properties 31 | source.set_property("pattern", 0) 32 | 33 | # start playing 34 | ret = pipeline.set_state(Gst.State.PLAYING) 35 | if ret == Gst.StateChangeReturn.FAILURE: 36 | print("ERROR: Unable to set the pipeline to the playing state") 37 | 38 | # wait for EOS or error 39 | bus = pipeline.get_bus() 40 | msg = bus.timed_pop_filtered( 41 | Gst.CLOCK_TIME_NONE, 42 | Gst.MessageType.ERROR | Gst.MessageType.EOS 43 | ) 44 | 45 | if msg: 46 | t = msg.type 47 | if t == Gst.MessageType.ERROR: 48 | err, dbg = msg.parse_error() 49 | print("ERROR:", msg.src.get_name(), " ", err.message) 50 | if dbg: 51 | print("debugging info:", dbg) 52 | elif t == Gst.MessageType.EOS: 53 | print("End-Of-Stream reached") 54 | else: 55 | # this should not happen. we only asked for ERROR and EOS 56 | print("ERROR: Unexpected message received.") 57 | 58 | pipeline.set_state(Gst.State.NULL) -------------------------------------------------------------------------------- /asset/CV.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/CV.jpg -------------------------------------------------------------------------------- /asset/ML.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/ML.jpg -------------------------------------------------------------------------------- /asset/computer_vision_with_embedded_ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/computer_vision_with_embedded_ml.png -------------------------------------------------------------------------------- /asset/cover_image.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/cover_image.jpeg -------------------------------------------------------------------------------- /asset/intro_to_embedded_ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/intro_to_embedded_ml.png -------------------------------------------------------------------------------- /asset/making-things-smarter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/making-things-smarter.png -------------------------------------------------------------------------------- /asset/week3-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/week3-tasks.png -------------------------------------------------------------------------------- /asset/week3_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/week3_reading.png -------------------------------------------------------------------------------- /asset/week4-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/week4-tasks.png -------------------------------------------------------------------------------- /asset/week4_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AISaturdaysLagos/edge-computing/0173ff91749eddf0993034fa9f0077309e13cb8d/asset/week4_reading.png -------------------------------------------------------------------------------- /week1/README.md: -------------------------------------------------------------------------------- 1 | # AI6LAGOS EDGE COMPUTING WORKSHOP 2023 2 | 3 | ### WEEK1 Tasks 4 | - Installation of Edge Impulse CLI on local machine - [Link](https://docs.edgeimpulse.com/docs/edge-impulse-cli/cli-installation) 5 | - For Windows users, you can install Edge Impulse CLI on WSL - [Link](https://forum.edgeimpulse.com/t/wsl-windows-subsystem-for-linux-edge-impulse-cli/5843) 6 | 7 | ![Cover Image](../asset/intro_to_embedded_ml.png) 8 | - Enroll for module 1 - [Link](https://www.coursera.org/learn/introduction-to-embedded-machine-learning) 9 | ![Cover Image](../asset/computer_vision_with_embedded_ml.png) 10 | - Enroll for module 2 - [Link](https://www.coursera.org/learn/computer-vision-with-embedded-machine-learning) 11 | - Watch: Jetson AI Fundamentals - First Time Setup with JetPack (S1E1) - [Link](https://www.youtube.com/watch?v=uvU8AXY1170&list=PL5B692fm6--uQRRDTPsJDp4o0xbzkoyf8) 12 | - Watch: Jetson AI Fundamentals - S1E2 - Hello Camera - [Link](https://www.youtube.com/watch?v=zsjcSapzUfU&list=PL5B692fm6--uQRRDTPsJDp4o0xbzkoyf8) 13 | - Watch: Jetson AI Fundamentals - S1E3 - Image Classification Project - [Link](https://www.youtube.com/watch?v=rSqIvLQ8Meg&list=PL5B692fm6--uQRRDTPsJDp4o0xbzkoyf8) 14 | 15 | 16 | ------------------------------------------------------------ 17 | ## Setting Up Jetson 18 | Tools and Softwares: 19 | - Balena Etcher to flash the SD card 20 | 21 | Hardware: 22 | - [Jetson Nano 2GB Developer](https://www.sparkfun.com/products/17244) or [Nvidia Jetson Nano Developer Kit](https://www.sparkfun.com/products/16271) 23 | - An SD Card (recommended 32 GB UHS-1 card according to Nvidia) 24 | - An ethernet cable / Wifi adapter 25 | - Depending on how you want to set up your Jetson Nano you'll need either: 26 | an extra computer to communicate with the Jetson Nano directly from the host computer 27 | - or a monitor, keyboard and mouse to interact directly with the Jetson Nano. 28 | ## Install Docker and Docker Compose 29 | Navigate to the directory: 30 | ``` 31 | cd week2 32 | ``` 33 | The make all scripts writable 34 | ``` 35 | sudo chmod +x *.sh 36 | ``` 37 | Install `curl` with the following command 38 | ``` 39 | sudo apt install curl 40 | ``` 41 | Install jetson-stats 42 | ``` 43 | sudo -H pip3 install jetson-stats / sudo pip3 install -U jetson-stats 44 | ``` 45 | Reboot the device 46 | ``` 47 | reboot 48 | ``` 49 | If issue persist in jetson-stats try this - [Link](https://rnext.it/jetson_stats/troubleshooting.html) [Link2](https://forums.developer.nvidia.com/t/jtop-install-fail/203576/4) 50 | #### Connecting to Jetson: 51 | We can connect to the Jetson on our primary computer, open a serial console (PuTTY on Windows or screen on macOS and Linux), see the full instruction here. 52 | 53 | ### Docker 54 | ``` 55 | echo "sudo docker run --runtime nvidia -it --rm --network host \ 56 | --volume ~/nvdli-data:/nvdli-nano/data \ 57 | --device /dev/video0 \ 58 | nvcr.io/nvidia/dli/dli-nano-ai:v2.0.2-r32.7.1" > docker_dli_run.sh 59 | ``` 60 | ## Reference 61 | - [Installation of Edge Impulse](https://docs.edgeimpulse.com/docs/edge-impulse-cli/cli-installation) 62 | - [Introduction to Embedded Machine Learning](https://www.coursera.org/learn/introduction-to-embedded-machine-learning) 63 | - [Computer Vision with Embedded Machine Learning](https://www.coursera.org/learn/computer-vision-with-embedded-machine-learning) 64 | -------------------------------------------------------------------------------- /week2/README.md: -------------------------------------------------------------------------------- 1 | # AI6LAGOS EDGE COMPUTING WORKSHOP 2023 2 | WEEK2 Tasks 3 | ![Embedded ML](../asset/intro_to_embedded_ml.png) 4 | ![ML](../asset/ML.jpg) 5 | ---------------------------------------------------------- 6 | ![Embedded CV](../asset/computer_vision_with_embedded_ml.png) 7 | ![CV](../asset/CV.jpg) 8 | 9 | 10 | ## Reference 11 | - [Introduction to Embedded Machine Learning](https://www.coursera.org/learn/introduction-to-embedded-machine-learning) 12 | - [Computer Vision with Embedded Machine Learning](https://www.coursera.org/learn/computer-vision-with-embedded-machine-learning) 13 | -------------------------------------------------------------------------------- /week2/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # First update os 3 | # Setup the distribution to pick a specific version of Docker 4 | # distribution=$(. /etc/os-release;echo $ID$VERSION_ID) 5 | # curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - 6 | # curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list 7 | 8 | sudo apt-get update 9 | # sudo apt-get install nvidia-docker2=2.8.0-1 10 | 11 | # Ensure all dependencies have been installed 12 | sudo apt-get install -y python3-pip 13 | sudo apt-get install -y python-pip 14 | sudo apt-get install -y python3-setuptools 15 | 16 | # Install Docker compose 17 | sudo apt-get install curl libffi-dev python-openssl libssl-dev zlib1g-dev gcc g++ make -y 18 | python3 -m pip install --upgrade pip 19 | sudo pip3 install docker-compose 20 | -------------------------------------------------------------------------------- /week3/README.md: -------------------------------------------------------------------------------- 1 | # AI6LAGOS EDGE COMPUTING WORKSHOP 2023 2 | WEEK3 Reading 3 | ![Embedded CV](../asset/computer_vision_with_embedded_ml.png) 4 | ![CV](../asset/week3_reading.png) 5 | 6 | ## Class Task 7 | #### Task 1 : Run the image classification in the DLI program. 8 | ![](../asset/week3-tasks.png) 9 | 10 | #### Task 2 : Setup and build object detection model for computer vision task 11 | ![CV](../asset/making-things-smarter.png) 12 | ## Reference 13 | - [Computer Vision with Embedded Machine Learning](https://www.coursera.org/learn/computer-vision-with-embedded-machine-learning) 14 | - [High-Speed Object Detection with Jetson Nano and Edge Impulse](https://www.youtube.com/watch?v=_T6h3Jmq2Yk) 15 | - [Nvidia Jetson Nano](https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-cpu-gpu-targets/nvidia-jetson-nano) 16 | - [Face mask detector using Edge Impulse and Nvidia Jetson](https://www.hackster.io/shahizat/face-mask-detector-using-edge-impulse-and-nvidia-jetson-8c4dda) 17 | - [Jetson Product Lifecycle](https://developer.nvidia.com/embedded/lifecycle) 18 | - [Data Collection](https://d3c33hcgiwev3.cloudfront.net/PWxt1WoJS_qsbdVqCev6SA_0b8fe1563e5a421eb9aab4af06a64ef1_slides-1.1.3.pdf?Expires=1685836800&Signature=ZPePuRmXwr6nYWlnN1b9kMaqSNjoi4IJVY9G95KxxG3XQ7AwNLS98WDH9oqAsDt~e7P5CBeoUPXPuB98iS7MmDD~t54814~lH1LjR5fB-glyh3xsCb25g34y36ElodL9QFwifCAtDp~AIB0w09aOZYrPZh2wDlY2novF7cYR-oc_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) 19 | - [Review of Module 1](https://d3c33hcgiwev3.cloudfront.net/48r074D2SniK9O-A9hp4DQ_c50632c224df4950b1e6d4e6beb663f1_slides-1.5.2.pdf?Expires=1685836800&Signature=auSFLC6cHOQgHDpWdQ796WJQ8XatPc6T4kLWp4HJmjhwAYgwFv9u1dhgFnwmSGdM4eDjnfHRqCvAFofQGaGrfFICegtvA-urV9LRpIhiAUV~i3w-Gcmw23UKD9w4HrZNAT3toQx6rlp5IdaDR4BNUELROE71rrRUUe5IcTLswPU_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) 20 | - [Overview of Digital Images](https://d3c33hcgiwev3.cloudfront.net/282OCuhFTlyNjgroRb5crg_da0b4ed3eef94242965bf4f014c5b6f1_slides-1.1.2.pdf?Expires=1685836800&Signature=ApXdiM1-n7V8wpBVtg7jLRoMISwtwouq3rFGTS1kKIE5BHygcOZVvXB45OvAeVCOBfFHU77Nmqe5eBHg1zRH40AadV3NHWPH40Sb0mbGFIxlNcIlM2pUV43DVXYHMYc~Sb~uyhmuBZUjHpQ~jsh0nShxM37sLGdpDs-LNK7~Y64_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) -------------------------------------------------------------------------------- /week4/README.md: -------------------------------------------------------------------------------- 1 | # AI6LAGOS EDGE COMPUTING WORKSHOP 2023 2 | WEEK4 Reading 3 | ![Embedded CV](../asset/computer_vision_with_embedded_ml.png) 4 | ![CV](../asset/week4_reading.png) 5 | 6 | ## Class Task 7 | #### Task 1 : Run the image regression task in the DLI program. 8 | ![](../asset/week4-tasks.png) 9 | 10 | #### Task 2 : Setup and build object detection model for computer vision task using Edge Impulse 11 | ##### On x86_64(Ubuntu/Debian): 12 | You can follow the instruction - [Link](https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-cpu-gpu-targets/linux-x86_64) 13 | ``` 14 | sudo apt install -y curl 15 | curl -sL https://deb.nodesource.com/setup_14.x | sudo bash - 16 | sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps 17 | npm config set user root && sudo npm install edge-impulse-linux -g --unsafe-perm 18 | ``` 19 | ##### On Jetson: 20 | You can follow the instruction - [Link](https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-cpu-gpu-targets/nvidia-jetson-nano) 21 | ![CV](../asset/making-things-smarter.png) 22 | 23 | Before starting anything, it might be good to update everything. You can do that by entering the commands below: 24 | ``` 25 | sudo apt-get update 26 | sudo apt-get upgrade 27 | ``` 28 | From the terminal, run to install Edge Impulse and its dependencies: 29 | 30 | ``` 31 | wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/jetson.sh | bash 32 | ``` 33 | You should get a response that looks like the one below. 34 | ``` 35 | + edge-impulse-linux@1.4.3 36 | added 343 packages from 420 contributors in 81.696s 37 | ``` 38 | Now, use the below command to run Edge Impulse: 39 | ``` 40 | edge-impulse-linux 41 | ``` 42 | You can verify the device: 43 | 44 | For x86_64: 45 | ![x86_64](https://84771188-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGEgcCk4PkS5Pa6uBabld%2Fuploads%2Fgit-blob-455ffcd35daf137b99c4bf8a4c8bcf71261d8cea%2Fdcbbb78-screenshot_2022-01-18_at_105616.png?alt=media) 46 | 47 | For Jetson Nano: 48 | ![Jetson](https://84771188-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FGEgcCk4PkS5Pa6uBabld%2Fuploads%2Fgit-blob-63957e037f4a86a774117d684969c722396f079c%2F9d5f41e-screenshot_2021-04-14_at_123509.png?alt=media) 49 | 50 | You will be asked to log in to your Edge Impulse account. You’ll then be asked to choose a project, and finally to select a camera to connect to the project. 51 | 52 | ``` 53 | ai6-jetson@ai6jetson-desktop:~/Documents$ edge-impulse-linux-runner 54 | Edge Impulse Linux runner v1.4.3 55 | 56 | [RUN] Downloading model... 57 | [BLD] Created build job with ID 9690982 58 | [BLD] Connected to job 59 | [BLD] Scheduling job in cluster... 60 | [BLD] Container image pulled! 61 | [BLD] Job started 62 | [BLD] Scheduling job in cluster... 63 | [BLD] Container image pulled! 64 | [BLD] Job started 65 | [BLD] Exporting TensorFlow Lite model... 66 | [BLD] Exporting TensorFlow Lite model OK 67 | . 68 | . 69 | . 70 | . 71 | [BLD] Building binary OK 72 | [RUN] Downloading model OK 73 | [RUN] Stored model version in /home/ai6-jetson/.ei-linux-runner/models/187851/v10/model.eim 74 | [RUN] Starting the image classifier for Edge Impulse Experts / synthetic_data_with_nvidia_replicator_and_edge_impulse_v2 (v10) 75 | [RUN] Parameters image size 320x320 px (3 channels) classes [ 'fork', 'knife', 'spoon' ] 76 | [RUN] Using camera HD Pro Webcam C920 starting... 77 | [RUN] Connected to camera 78 | 79 | Want to see a feed of the camera and live classification in your browser? Go to http://19*.*.*.*:4912 80 | 81 | boundingBoxes 179ms. [{"height":136,"label":"fork","value":0.7591571807861328,"width":134,"x":0,"y":176},{"height":170,"label":"fork","value":0.6790993213653564,"width":52,"x":180,"y":3}] 82 | ``` 83 | # Deepstream SDK on Jetson 84 | ## Setting up Deepstream Docker on Jetson 85 | Pull Deepstream from Nvidia NGC: 86 | ``` 87 | sudo docker pull nvcr.io/nvidia/deepstream-l4t:6.0-samples 88 | ``` 89 | 90 | ``` 91 | i6-jetson@ai6jetson-desktop:~/Documents$ sudo docker pull nvcr.io/nvidia/deepstream-l4t:6.0-samples 92 | 6.0-samples: Pulling from nvidia/deepstream 93 | 3b65ec22a9e9: Pulling fs layer 94 | 9bfa49b064c8: Pulling fs layer 95 | cde16ef91ac2: Pulling fs layer 96 | 978ea3dcd5fb: Waiting 97 | cde16ef91ac2: Downloading [===============================> ] 30.46MB/47.88MB 98 | 25e1b86ea3b6: Downloading [> ] 11.34MB/1.086GB 99 | ab995ea0d0d0: Waiting 100 | 6f67c1a28e38: Waiting 101 | 1f4505fd2b95: Waiting 102 | 816c2238973f: Waiting 103 | Digest: sha256:8054daa024f2cc58d58678652be6f9b5e2e7512d1b87fd560ca98cdc758e247a 104 | Status: Downloaded newer image for nvcr.io/nvidia/deepstream-l4t:6.0-samples 105 | nvcr.io/nvidia/deepstream-l4t:6.0-samples 106 | ``` 107 | 108 | Start the Docker Container: 109 | ``` 110 | sudo chmod a+x deepstream.sh 111 | ``` 112 | Run the container in the docker container: 113 | ``` 114 | docker exec -it deepstream bash 115 | deepstream-app --version 116 | ``` 117 | 118 | ## Reference 119 | - [Computer Vision with Embedded Machine Learning](https://www.coursera.org/learn/computer-vision-with-embedded-machine-learning) 120 | - [High-Speed Object Detection with Jetson Nano and Edge Impulse](https://www.youtube.com/watch?v=_T6h3Jmq2Yk) 121 | - [Nvidia Jetson Nano](https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-cpu-gpu-targets/nvidia-jetson-nano) 122 | - [Face mask detector using Edge Impulse and Nvidia Jetson](https://www.hackster.io/shahizat/face-mask-detector-using-edge-impulse-and-nvidia-jetson-8c4dda) 123 | - [Jetson Product Lifecycle](https://developer.nvidia.com/embedded/lifecycle) 124 | - [Data Collection](https://d3c33hcgiwev3.cloudfront.net/PWxt1WoJS_qsbdVqCev6SA_0b8fe1563e5a421eb9aab4af06a64ef1_slides-1.1.3.pdf?Expires=1685836800&Signature=ZPePuRmXwr6nYWlnN1b9kMaqSNjoi4IJVY9G95KxxG3XQ7AwNLS98WDH9oqAsDt~e7P5CBeoUPXPuB98iS7MmDD~t54814~lH1LjR5fB-glyh3xsCb25g34y36ElodL9QFwifCAtDp~AIB0w09aOZYrPZh2wDlY2novF7cYR-oc_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) 125 | - [Review of Module 1](https://d3c33hcgiwev3.cloudfront.net/48r074D2SniK9O-A9hp4DQ_c50632c224df4950b1e6d4e6beb663f1_slides-1.5.2.pdf?Expires=1685836800&Signature=auSFLC6cHOQgHDpWdQ796WJQ8XatPc6T4kLWp4HJmjhwAYgwFv9u1dhgFnwmSGdM4eDjnfHRqCvAFofQGaGrfFICegtvA-urV9LRpIhiAUV~i3w-Gcmw23UKD9w4HrZNAT3toQx6rlp5IdaDR4BNUELROE71rrRUUe5IcTLswPU_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) 126 | - [Overview of Digital Images](https://d3c33hcgiwev3.cloudfront.net/282OCuhFTlyNjgroRb5crg_da0b4ed3eef94242965bf4f014c5b6f1_slides-1.1.2.pdf?Expires=1685836800&Signature=ApXdiM1-n7V8wpBVtg7jLRoMISwtwouq3rFGTS1kKIE5BHygcOZVvXB45OvAeVCOBfFHU77Nmqe5eBHg1zRH40AadV3NHWPH40Sb0mbGFIxlNcIlM2pUV43DVXYHMYc~Sb~uyhmuBZUjHpQ~jsh0nShxM37sLGdpDs-LNK7~Y64_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A) 127 | - [Nvidia Deepstream Docker](https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_docker_containers.html) 128 | - [Setting up Deepstream](https://chirag4798.medium.com/nvidia-deepstream-101-a-beginners-guide-to-real-time-computer-vision-afefcb5d7fba) 129 | - [Nvidia DeepStream 101: A step-by-step guide to creating your first DeepStream application](https://chirag4798.medium.com/nvidia-deepstream-101-a-step-by-step-guide-to-creating-your-first-deepstream-application-68148753cf96) -------------------------------------------------------------------------------- /week4/deepstream-old.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | xhost + 6 | 7 | sudo docker run \ 8 | -it \ 9 | --rm \ 10 | --net=host \ 11 | --runtime nvidia \ 12 | -e DISPLAY=$DISPLAY \ 13 | -v /tmp/argus_socket:/tmp/argus_socket \ 14 | -v /tmp/.X11-unix/:/tmp/.X11-unix \ 15 | -v /opt/nvidia/deepstream/deepstream \ 16 | nvcr.io/nvidia/deepstream-l4t:6.0-samples 17 | -------------------------------------------------------------------------------- /week4/deepstream_no_display.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | sudo docker run \ 6 | -it \ 7 | --rm \ 8 | --net=host \ 9 | --runtime nvidia \ 10 | -v /tmp/argus_socket:/tmp/argus_socket \ 11 | -v /tmp/.X11-unix/:/tmp/.X11-unix \ 12 | -v /opt/nvidia/deepstream/deepstream \ 13 | nvcr.io/nvidia/deepstream-l4t:6.1.1-samples -------------------------------------------------------------------------------- /week4/jetson.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | wget https://nodejs.org/dist/v12.13.0/node-v12.13.0-linux-arm64.tar.xz 5 | tar -xJf node-v12.13.0-linux-arm64.tar.xz 6 | cd node-v12.13.0-linux-arm64 7 | sudo cp -R * /usr/local/ 8 | cd .. 9 | sudo apt update 10 | sudo apt install -y gcc g++ make build-essential pkg-config glib2.0-dev libexpat1-dev sox v4l-utils libjpeg-turbo8-dev 11 | wget https://github.com/libvips/libvips/releases/download/v8.12.1/vips-8.12.1.tar.gz 12 | tar xf vips-8.12.1.tar.gz 13 | cd vips-8.12.1 14 | ./configure 15 | make -j 16 | sudo make install 17 | sudo ldconfig 18 | sudo npm install edge-impulse-cli -g --unsafe-perm=true 19 | sudo npm install edge-impulse-linux -g --unsafe-perm=true 20 | --------------------------------------------------------------------------------